LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LabVIEW as a Service - process stays in memory despite finishing execution

One thing to check what the application is returning when it shuts down, and the corresponding reaction that NSSM is setup to use. "Look in the Event Log for messages from nssm to see what exit codes are returned by your application."

Below is what the NSSM website has to say:

Actions on exit

To configure the action which nssm should take when the application exits, edit the default value of the keyHKLM\System\CurrentControlSet\Services\servicename\Parameters\AppExit. If the key does not exist in the registry when nssmruns it will create it and set the value to Restart. Change it to either Ignore or Exit to specify the action taken. nssm will only create this key if it doesn't already exist. Your changes will not be overridden.

To specify a different action for particular exit codes, create a string (REG_SZ) value underneath the AppExit key whose name is the exit code being considered. For example to stop the service on an exit code of 0 (which usually means the application finished successfully), create HKLM\System\CurrentControlSet\Services\servicename\Parameters\AppExit\0 and set it to Exit. Look in the Event Log for messages from nssm to see what exit codes are returned by your application.

If your application's exit code does not correspond to a registry entry, nssm will use the default value of AppExit when deciding what to do.

Chris Walker
Certified Labview Developer
0 Kudos
Message 11 of 23
(1,322 Views)

Has anybody acquired a solution to this problem?

0 Kudos
Message 12 of 23
(1,116 Views)

There have been several solutions/workarounds posed in this thread. What don't you like about them?

A more complex solution is to create your own DLL to interface to the Service Manager API and call that from your LabVIEW program. With some programming effort you can even use the callback from the service manager to send user events to your application to make it all work asynchronously. The alternative is to simply store the status from the callback in the DLL and poll it periodically from LabVIEW.

Rolf Kalbermatter
My Blog
0 Kudos
Message 13 of 23
(1,098 Views)

Which one is the solution? I don't see that any of them as an accepted answer.
In my case modifying the labview code is not an option, since we don't have the source code. We have a builded executable of the VI.

From that I made a service with NSSM and run the exe as a service.

Through ActiveX server I'm able to read/write some controls and indicators on the frontpanel from Python. However when we give NSSM the command to stop the service, it stays in the memory, and my python code keeps reading the frontpanel as it would be alive, but instead it should give me an error, that the labview app is not running..

0 Kudos
Message 14 of 23
(1,086 Views)

Well in that case I'm afraid you are stuck between a wall and a hard place. I don't have time to investigate why NSSM might not be able to properly terminate the LabVIEW process. Most likely it's possible to do but requires the LabVIEW process to be doing specific things in the event handling to make sure that the Application.Exit event does close every single resource including any VI frontpanel and/or VI reference.

LabVIEW executables have a bit of a different way of controlling life time of the process. It will stay alive for as long as there is somewhere a front panel open, even if it is hidden, which is exactly what you want for a service. So if you don't make sure that you explicitedly close every single front panel and according VI reference the process may be left in a hanging state eventhough there is no diagram running anymore. This is especially likely since Windows does a few special tricks with processes it executes in the Service Manager to make sure they can not interact with the user desktop in any way unless the process was specifically registered to be allowed to interact with the desktop by showing a dialog or something. If this is not disabled the application can keep trying to display modal dialogs as much as it wants but it will never be visible on the user desktop, making the process appear stuck as it is waiting for the acknowledgment of this dialog which can never happen. Newer Windows versions have more or less made this desktop interaction impossible since it poses potential security risks for the system integrity as a service by definition runs in a higher privileged level.

Rolf Kalbermatter
My Blog
0 Kudos
Message 15 of 23
(1,078 Views)

If you can send a command to NSSM to stop the service, perhaps send an additional command to kill the process running your application??? It is not a clean shutdown but at least it ends the process. A process can be terminated via the command line using the system exec vi. See the following post:

https://forums.ni.com/t5/LabVIEW/How-to-close-running-applications-listed-in-Application-tab-of/m-p/...

For example, you can poll the running processes via a command like this: 

cmd /c tasklist /FI "imagename eq notepad.exe" /V /FO "CSV" in the "System Exec.vi" and you can end it with

cmd /c taskkill /FI "imagename eq notepad.exe" /FI "PID eq

Chris Walker
Certified Labview Developer
0 Kudos
Message 16 of 23
(1,057 Views)

What this command does? I tried it, nothing happens.

0 Kudos
Message 17 of 23
(1,045 Views)

I wrote the command wrong... looks like I added some extra characters. Try: 

cmd /c taskkill /FI "imagename eq notepad.exe"

Please see attached.

Chris Walker
Certified Labview Developer
0 Kudos
Message 18 of 23
(1,037 Views)

Allright, there is a new phenomenon, but it is related to this topic, so if you don't mind I will write it here (sorry for the long post):

 

There is a python library, called: win32com LINK
It allows python to "talk" with COM objects and ActiveX servers.
For example with this few lines of code I'm able to access a VI's frontpanel, and get the value of the 'valve01' field, if the VI is opened in the IDE:

import win32com.client

labview = win32com.client.Dispatch("Labview.Application")
VI = labview.getvireference(r'path-to-vi/vi_name.vi')
print(VI.getcontrolvalue("valve01"))

And here is the version, that connects to a builded Labview executable (this way, no Labview IDE is needed, but you need to enable ActiveX server):

 

import win32com.client

labview = win32com.client.Dispatch("ActiveXServerName.Application")
VI = labview.getvireference(r'path-to-vi/vi_name.exe/vi_name.vi')
print(VI.getcontrolvalue("valve01"))

Otherwise, if the VI is not opened I get an error, that it couldn't connect, but that is perfectly fine.


Here is a list of all available commands that you can get this way, to talk to the VI: LINK

So far so good, you can connect to the VI without having to modify the Labview code itself.

But I would like to take it the one step further. With an application called NSSM, I'm able to make the builded executable into a background service. I'm geting strange henomenons with this method:

I register a new process, and it runs the builded LV executable in the background. Under Windows Task Manager I see it as an admin process. And when I connect to it the way I described above, it makes another instance of that process, this time the username is mine. I tried it with a third dummy user, in that case it opens up a third instance. This is not desired at all, only one instance should run, the admin process. If I shut down the process completely, and I make sure the process is not in the Task Manager, I'm still able to connect to it with this line:

labview = win32com.client.Dispatch("ActiveXServerName.Application")

, instead it should give me an error that it is not running, but it doesn't and just brings up the frontpanel.

So do you have any idea, or tip or something, why is the activex server, or the labview executable seemingly continue to run, even if I give NSSM to terminate the process, of even if I terminate it myself by hand??

 

 

 

0 Kudos
Message 19 of 23
(1,002 Views)

Windows Services don't just run in the background of your login session. They can't as they must be able to run in the background even if no user is logged in. Therefore they are started up in Session 0 when the computer starts up. But that has certain limitation that Microsoft increased in Windows Vista with Service hardening. The purpose is to prevent a compromised service to be able to control everything else as was the case in earlier Windows systems where a service would execute under the System account, which is pretty much unlimited and allows a service to do anything including formatting your harddisk or grabbing any file on disk including highly sensitive data files and send them off to whoever is its master.

 

The ActiveX functionality is built on COM which only works within a single Session, so you can not access the ActiveX interface for a process running as a service in Session 0 from your program running in a regular user account under any other Session but 0 and you can not start your user session in Session 0. All for the purpose of security. Theoretically there is a possibility to route ActiveX through DCOM instead, which is the distributed version of COM and then runs through the network and could span across Session boundaries, but setting up DCOM is very involved and requires lots of very detailed system knowledge that I don't have.

 

Basically trying to communicate to a process running as service through ActiveX from your normal user session is not possible.

 

 

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 20 of 23
(975 Views)