LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Get VI ref for LV executable set to allow multiple instances

I have inherited some LabVIEW code, which I'm not inclined to change, that will run as an executable with multiple instances set to true on a standard Windows PC. There could be up to four of these executables running in parallel on one machine. I need to interact with these four executables programmatically, and I was hoping to use VI Server to get and put values into the FP controls. However, the visible title of these instances is not necessarily known as they change their names depending on their state, which includes a floating point numeric (for example "My Software n=1.234")

 

Question: From within LabVIEW (my own executable), how do you get a reference to another LabVIEW executable on the same target when there could be n instances of that executable?

 

Is it possible to get a list of those VIs that are running as an executable? I tried "Application:All VIs In Memory" property but it returns only the VI that the call is inside, and doesn't see the running executable (I'm not surprised).

 

I thought about using Windows calls to retrieve all window titles and parse them for this executable, but that might not work as the numeric in the title changes rapidly, so no sooner than I've worked out the title it'll already have changed and will no longer be valid for Open VI Reference. 

 

I'll continue to try a few other ideas, but would appreciate any input from you smart folk out there Smiley Happy

Thoric (CLA, CLED, CTD and LabVIEW Champion)


0 Kudos
Message 1 of 8
(3,106 Views)

@Thoric wrote:

 

Is it possible to get a list of those VIs that are running as an executable? I tried "Application:All VIs In Memory" property but it returns only the VI that the call is inside, and doesn't see the running executable (I'm not surprised).


Nor should you be. VIs don't "run as executables" so there's no reason this would work. The "Application" part of the property you used *is* the executable.

 

What you will want to do is configure each instance of the EXE to have different VI server settings (specifically, the port number or service name) and use the Open Application Reference primitive with that info to get a reference to the app. Normally, this is controlled from the INI file, but since they share the file, I assume you will have to use property nodes to configure it dynamically. I have no practical experience with this, so I can't say what the pitfalls will be (e.g. is dynamic setting even allowed (probably yes, but I seem to remember that in the past there were some issues with it, at least inside LV)? Does a remote connection have all the permissions you need?).

 

Another alternative is to use something like LVx or networked actors to send commands to the EXE and then translate it locally.


___________________
Try to take over the world!
Message 2 of 8
(3,093 Views)

Hi tst,

 

I'm a little confused by this. I've been looking in greater detail at Open Application Reference to discover how I gain a new app ref to the executable isntance. The inputs to this function are Machine Name and Port Number. I've read in another thread that you point to the exe in the machine name input, but unless I provide a IP address (or machine name) it throws an error. How does one use Open App Reference to get an application reference to an executable? 

 

I tried setting the server.tcp.serviceName value to something simple, but I don't see how to use this information in the Open App Ref primitive.

 

Forgive my ignorance on this, programmatic control between separate exes is fairly new ground for me.

Thoric (CLA, CLED, CTD and LabVIEW Champion)


0 Kudos
Message 3 of 8
(3,085 Views)

Question: From within LabVIEW (my own executable), how do you get a reference to another LabVIEW executable on the same target when there could be n instances of that executable?

 

 I need to interact with these four executables programmatically.


 

I'm digging deep here.....  Lets toss out any VI ref or method off the top.  You need to interact with running applications.  To make things just a bit more strange you need to interact with specific instances of the same application while those instances are <poofing> in and out of existance beyond the knowledge of "YourApp.exe"

 

At least they are on the same targetSmiley Happy

 

I cannot think of a elegant way to identify a specific app instance of an exe without the app instance itself supplying some of that info upon launch.  The OS is doing the launching and interaction with the app instances and the LVRTE is merely helping interperate the instructions contained in the executable.

 

Publishing the RunTime read only property App:Active:App to an element of  a single process shared variable array of "apps.active"  might help.    YourApp can read the array and learn what app instances are active.  But I may be going down a rabbit hole here since that merely filters the problem down to "Finding one of a few instances of a particular app that is currently running"  And it involves modifying the application you inherited.  You said you did not want to modify InheritedApp but, IF you chose to, or it becomes necessary anyway, pass App:Active:App + whatever you need to specify instance out of the app when it is called- ( even if its just a filename YourApp and the InheritedAppInstance can use as a data transfer point)

 

Time for me to sit back and learn something new today.

 

EDIT: Just did "What you will want to do is configure each instance of the EXE to have different VI server settings (specifically, the port number or service name) "


"Should be" isn't "Is" -Jay
Message 4 of 8
(3,080 Views)

Well, I'm nearly there. WIth further research I've found an example project that demonstrates one executable attaining an application reference to another executable. Now to see if I can use that reference to control the second executable.

 

One downside: it requires a VI Property being set, the TCP.Active property. Once set to True it accepts incoming VI Server requests. Thing is, I don't want to change the inherited executable. However, this tiny addition might be acceptable.

Thoric (CLA, CLED, CTD and LabVIEW Champion)


0 Kudos
Message 5 of 8
(3,067 Views)

Can you post the example or its location if the Example Finder would locate it?  and, do you mean "Short Name: Srvr.TCPActive"?  That's one I've never played with before.


"Should be" isn't "Is" -Jay
0 Kudos
Message 6 of 8
(3,063 Views)

@Thoric wrote:

I've read in another thread that you point to the exe in the machine name input.

Incorrect, as you've seen. The machine name input is just that. Since it's the same machine, you can use localhost (or I think an empty string also works). The key is the port number - each instance of VI Server listens on a different port, so that's what you have to configure. That's why the important property for what you want is not the Active property (that can probably be configured statically in the INI file), but the port property, which you need to somehow set dynamically to a different value for each separate instance (i.e one listens on port 4001, the next on 4002 and so on).

 

The service name is simply something that NI uses to abstract this a bit - there's an NI service which knows how to map these names to ports, but I have no idea exactly how this is configured. Presumably it's also done from the VI Server page/INI file. You don't actually need to use it.

 

I would suggest you also look at Norm's LVx examples, as I believe he does go into VI server connections between EXEs.


___________________
Try to take over the world!
Message 7 of 8
(3,058 Views)

OK, thanks guys. This is what I know now:

 

Set the following InheritedApp.ini file tags to enable the TCP service for remote connections and choose a unique port:

server.tcp.access="+*"
server.tcp.port=3364
server.tcp.enabled=True

 

Run the InheritedApp application.

 

In my own code, use Open App Reference with machine name as "localhost" and the same port number as used by the target application. This gets you a reference to the target app. To get the top level VI reference, use Open VI Reference with this app ref and the top level VI name. Bingo. I now have a reference to the VI within the executable.

 

For the next, parallel instance of InheritedApp, change the server.tcp.port value to something else and launch it again, rinse and repeat for each.

 

I've not actually tried this yet, but I suspect I'll get multiple parallel instances of InheritedApp and references to each in my own LabVIEW app, thus allowing me to programmatically control them all. Fingers crossed this works....

 

Edit: Yup! Certainly in the first test I was able to get one instance loaded up and talking through VI Server. Now to see if this scales up for multiple instances of InheritedApp.exe...

 

Jeff: Inspiration also from this thread

Thoric (CLA, CLED, CTD and LabVIEW Champion)


Message 8 of 8
(3,051 Views)