11-10-2015 03:52 PM
I've noticed and issue with the System Exec.vi which I wanted to detail here. I will also make reference to System Exec+.vi which can be found here http://www.ni.com/example/29935/en/
I am attempting to connect to and send commands to a camera. The camera has it's own command line or shell that I can access for a faster response. After opening a connection to the camera's shell, I am using Windows APIs to send keystrokes to the shell in order to send commands to the camera. To access the camera's shell, I have written a program in C to check for a connection, open the shell, and then verify a valid connection. I am running this C program from Labview, and leaving the shell window open and minimized. In order to open a window for the camera's shell, I am running the system command:
start "name" /MIN <command> <args>
I want Labview to wait for completion of the C code (.exe file), which is the default (true) option for both System Exec.vi and System Exec+.vi while leaving the camera's shell window open and minimized. I am running Labview 2011 SP1 on Windows 7. I would also like access to the return code and stdout values provided by the System Exec.vi so I can know if my code executed without issue or not. These outputs are not provided by System Exec+.vi.
Running my C code in the command line leaves me with an open shell window and an available command promt. The "start" command in windows serves to run the command in a new window and not wait for completion.
If I run my code from labview using System Exec.vi, the System Exec call never finishes. Labview ends up waiting for the new shell window to close before it will release control of that call. This behavior is the issue, and is contrary to how the Windows command line treats the 'start' command. To reiterate, I am running code from Labview with the wait for completion condition, and this code is in turn opening another window with the do not wait for completion condition; while the code is completing (it's minimized window closes), Labview is waiting for the new window to close, escentially waiting for it to complete, despite it being opened with a do not wait condition.
Of interest is the System Exec+.vi behavior. System Exec+ behaves as I would expect, waiting for the main C code to complete, but not waiting for the additional shell window to complete. The downside to this VI call is the lack of access to return code, stdout, and stderr. System Exec.vi is locked and the block diagram for it cannot be accessed. System Exec+.vi can be accessed, but it relies on a DLL that I seem to be unable to uncompile, so I cannot attempt to edit it's functionality. It is my opinion that the System Exec.vi should behave more like the command line and System Exec+.vi when it comes to waiting for completion. My suspicion is that it is improperly looking for children of the process it creates and not looking for completion returns from the command line it is calling.
My solution: In order to get the desired result, I broke my code up into three chunks. First, I run some C code to check for a connection and do some housekeeping using System Exec, waiting for completion and returning a pass or fail condition. Then I run a short batch file using System Exec+, opening the new shell window, waiting for completion of the batch file but not waiting for the shell to close, and receiving no status on success or failure. Finally, I run the rest of the C code to check that the established connection is working using System Exec, waiting for completion and and returning a pass or fail condition.
Hopefully this post can serve in part as a bug report and in part as information for anyone else trying to do something similar. Again I reiterate that System Exec.vi does not function as I would expect, but that a workaround can be made through a combination of System Exec and System Exec+. Cheers.
11-10-2015 04:35 PM
Have you tried using, as the command for System Exec, "cmd /c [path to your exe]"? It's been suggested as a solution to similar problems elsewhere on this forum.
11-11-2015 07:39 AM
There is probably a fundamental difficulty in what you would like to have. You do want to have the exit status and standard IO values but do not want to wait until the secondary program has finished. That is theoretically possible for the standard IO although definitely not very clearly defined. When should the System Exec stop waiting for the secondary command and assume that there won't be any more standard IO coming? The exit status (return value as you call it) can only be retrieved after the program has clearly exit, so that definitely prevents the wait until completion to be set to false.
It's either startup and forget (wait until completion false) or startup, wait for completion and return standard IO and exit code. Anything else is shaky at best and never can be made to reliably work.
11-11-2015 08:52 AM - edited 11-11-2015 08:55 AM
I've actually written a little OOP-library that can interactively interface to a command-line application using the .NET Process library. It's meant as a replacement for System Exec where you want to read the console output of the process (e.g. when it shows status) or want to interact with a command-line application.
Have a look at the attached project/LabVIEW class in LV2013. The included example allows you communicate with a command prompt - but you can modify it to talk to your command-line application. It's not 'complete' but it should be enough to get you started.
It handles things like the application exiting itself (e.g. using an 'exit' command) and you can also force-close it from the example (it tries to call wm_close and if that doesn't work, it kills the process). It's a bit flaky when doing asynchronous reads (the .NET data in event doesn't fire until a newline) but otherwise seems to work OK. I might have some hanging references somewhere as well.
11-11-2015 12:39 PM
@rolfk, I would agree with you, except System Exec+ does exactly what I want it to do. It waits for the first call to finish, and then moves on. The external code should be telling Labview when it is done executing, and it is not waiting on the second window, so it does finish at somepoint. Run my code from a command prompt, and the command prompt doesn't lock up (because I used 'start'). Even though the other window is still open, the command prompt get's a return code, stdout, and stderr, and moves on for the next input. Labview and System Exec should behave the same way imho. See below for an example VI.
@Sam_sharp, thanks. Seems like a neat tool after playing with it for a few minutes. Appreciate you sharing. It seems to treat 'start' correctly at least, though it's not a perfect test because now I'm running it as a batch file. Thanks.
@nathand, hadn't come across that, but just tried it and no luck.
I made a little demo VI that is attached (meant for running on Windows). Go into the block diagram and run the code four times, toggling to each of the states of the two boolean constants (TT, TF, FT, FF). In 3/4 cases, the VI will end in less than a second. In one case, the VI will remain running until the pop up closes. By the definition of the 'start' command (as I understand it), all four cases should end without waiting for the window to close.
Run the command <start "window name" timeout 2000> from a command prompt, and you will get a new window that is waiting while the first window is available for new input. I should stress that I'm not a command line expert, I just know when behavior doesn't match from one place to another. It seems that System Exec does not match the functionality of the windows command line.