# Programmatically Add Script

**URL:** <https://forum.inductiveautomation.com/t/programmatically-add-script/112165>\
**Category:** Module Development\
**Tags:** ignition81\
**Created:** [November 13, 2025, 5:24pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165 "2025-11-13T17:24:39Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [November 13, 2025, 5:24pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/1 "2025-11-13T17:24:39Z")

</div>

I am trying to programmatically add a script to a window (from within my module) on the InternalFrameActivated listener. It seems that I could leverage the ComponentScriptEditor class, but I am not having luck in that direction. What would be the most sensible approach to this task? I understand this is far in the weeds, but I like to experiment.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [November 13, 2025, 5:32pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/2 "2025-11-13T17:32:28Z")

</div>

> [@Porter\_Ellis](#):
>
> What would be the most sensible approach to this task?

To not do this.

Adding scripts to windows and components is a task for the future user running the designer.

On top of that, the techniques used by Ignition to hold these scripts, while relatively stable, are implementation details that can be changed by IA at any future release.

What, _ **exactly** _, do you think you need this for?

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [November 13, 2025, 5:35pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/3 "2025-11-13T17:35:33Z")

</div>

As a module developer I have strived to implement code that reduces setup and provides functionality. The company I work for has many clients, and consequently many projects. My module requires a script to be applied to each window that needs the module functionality, which can be tedious. I have written the script in a way that makes it window-agnostic, meaning I can paste the same script into every window. If I could do this programmatically instead of via the designer, the module would be easier to install and consequently more easily sold.

This functionality could also be useful for some agentic modules I have planned in the future.

---

<div class="post-metadata">

**Author:** ![Leor\_Fishman](https://avatars.discourse-cdn.com/v4/letter/l/e19adc/32.png) [@Leor\_Fishman](https://forum.inductiveautomation.com/u/Leor_Fishman)\
**Post date:** [November 13, 2025, 5:49pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/4 "2025-11-13T17:49:48Z")

</div>

what do you mean by adding a script to the window?  
gateway event script on startup?

Prop binding script?

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [November 13, 2025, 5:52pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/5 "2025-11-13T17:52:46Z")

</div>

> [@Porter\_Ellis](#):
>
> on the InternalFrameActivated listener.

Adding a script to a listener on the window

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [November 13, 2025, 6:14pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/6 "2025-11-13T18:14:07Z")

</div>

> [@Porter\_Ellis](#):
>
> My module requires a script to be applied to each window that needs the module functionality

You should be writing a java listener for this task, and adding it to windows at **runtime** when your module functionality is invoked.

Are you supplying a Vision component? If so, have the component ensure the window listener is attached when its startup method is called.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [November 13, 2025, 6:19pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/7 "2025-11-13T18:19:32Z")

</div>

The script is built to tell a client tag which window has become focused. I cannot pair this with the module’s overall functionality because the component is rooted in a popup and relies on the tag to tell it which window is active.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [November 13, 2025, 6:29pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/8 "2025-11-13T18:29:07Z")

</div>

It still doesn't belong in the user's event script. It belongs in a window event listener. Provide a script function that attaches the desired listener to a given window if not already attached. Or provide custom `openWindow()` script functions that do this in addition to the normal window open operations.

Perhaps explore the use of `FPMIApp.setWindowOpener()`. (Would require some reflection, I presume.)

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [November 13, 2025, 6:35pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/9 "2025-11-13T18:35:42Z")

</div>

Could I override the normal behavior of an existing event listener and add my tag writing functionality under the hood? Or would it be better to attach a brand new listener? Furthermore, is it possible to attach a listener to a window that is not currently open?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [November 13, 2025, 6:38pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/10 "2025-11-13T18:38:19Z")

</div>

You need to use a separate listener, leaving the IA listener to do its normal thing.

You need to add your listener to an open window. There's no way to add to a closed window.

Perhaps you should write a java scheduled task that checks every few seconds for the existence of windows that do not have the listener, and just fix them.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [November 13, 2025, 6:41pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/11 "2025-11-13T18:41:56Z")

</div>

How would I replicate the behavior of InternalFrameActivated in a new listener? I need that exact behavior in order for the module to work as intended.

Or perhaps I can avoid this entirely if there is a java-accessible property for the currently active/focused window?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [November 13, 2025, 6:44pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/12 "2025-11-13T18:44:14Z")

</div>

It is a standard Java Swing Listener:

> **[InternalFrameListener (Java SE 17 & JDK 17)](https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/javax/swing/event/InternalFrameListener.html)**
>
> declaration: module: java.desktop, package: javax.swing.event, interface: InternalFrameListener

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [November 13, 2025, 6:49pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/13 "2025-11-13T18:49:09Z")

</div>

Without diving into the whole rest of this thread, I'll mention [`VisionDesktop.addDesktopListener()`](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.50/com/inductiveautomation/factorypmi/application/VisionDesktop.html#addDesktopListener(com.inductiveautomation.factorypmi.application.model.DesktopListener))

Which is the API the 'current window' system client tag uses to know when to reevaluate, for instance:  
`appContext.getPrimaryDesktop().addDesktopListener(this);`

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [November 13, 2025, 7:01pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/14 "2025-11-13T19:01:35Z")

</div>

Oooooo! That would notify the module when any new window is opened, which could then add the necessary listener on the fly, reliably.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [November 13, 2025, 8:23pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/15 "2025-11-13T20:23:59Z")

</div>

Does the `DesktopListener()`keep track of the focused window or just the last window opened?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [November 13, 2025, 8:34pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/16 "2025-11-13T20:34:26Z")

</div>

It doesn't keep track of anything; it's just a listener interface. If you want to track any state you have to do it yourself.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [November 13, 2025, 11:43pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/17 "2025-11-13T23:43:08Z")

</div>

One more small issue finishing this setup. The InternalFrameEvent can only return the local window name instead of the Vision window path. What would be the best way to get the Vision window path from the InternalFramEvent or it’s respective local window name?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [November 14, 2025, 12:00am UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/18 "2025-11-14T00:00:30Z")

</div>

If it's an instance of `FPMIWindow` it'll have a `com.inductiveautomation.factorypmi.application.FPMIWindow#getPath` method.

---

<div class="post-metadata">

**Author:** ![Porter\_Ellis](https://avatars.discourse-cdn.com/v4/letter/p/ed8c4c/32.png) [@Porter\_Ellis](https://forum.inductiveautomation.com/u/Porter_Ellis)\
**Post date:** [November 14, 2025, 6:44pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/19 "2025-11-14T18:44:03Z")

</div>

Perfect. Writing a `DesktopListener` into the `OnStartup` method of my component, then using the event to get the active window path did the trick. But if I was able to get the VisionClientContext into the ClientHook I could add the `DesktopListener` without instantiating my component. Is this possible? If so, how would I get the VisionClientContext object into the ClientHook? I haven’t had luck so far.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [November 14, 2025, 7:14pm UTC](https://forum.inductiveautomation.com/t/programmatically-add-script/112165/20 "2025-11-14T19:14:55Z")

</div>

`FPMIApp` has a static getter:  
`com.inductiveautomation.factorypmi.application.FPMIApp#getInstance`  
And there's a `getAdapterContext()` method on the parent class of `FPMIApp`.

[Next page](https://forum.inductiveautomation.com/t/programmatically-add-script/112165.md?page=2)
