Run Win32 executable and get status of completion...

Hi all,
I'm setting up an function that runs several Win32 executables (depending on the number of cores I have available) using matlab system function. The result is a bunch of DOS windows indicating the progress of the program which are closed automatically when the program finishes or crash. The next steps of the function are: (1) detect when each executable stop, (2) confirm that all the files where successfully created and (3) update a log file. While (2) and (3) are easy to address, I'm stuck in (1). I though that, by using:
[status, result] = system('command')
I would get any information regarding the end of the executable run, but this is not the case, as status/result variables are not updated in the end. Could someone please provide me a clue on how can I address this issue!
Thanks in advance!!

2 Comments

Doesn't system usually only return after the process is complete? (unless your code starts something else that detaches)
It seems to return when it is executed.

Sign in to comment.

Answers (2)

dpb
dpb on 28 Sep 2017
Edited: dpb on 28 Sep 2017
I answered this in your question added to the other thread; this confirms the issue is the one I addressed there -- Win32 programs don't have a console and so don't write anything to stdout so you can't get any information back this way from the program inside the detached process.
You could try to wrap the program call in a batch file that returns a status itself but there again you likely run into "issues" trying to tell whether the program terminated normally or not.
About the only way to do something like this for a program that wasn't designed for interprocess communication is for it to be able to write a log file or some other static object that the dispatching process can query or, use the TASKLIST command utility to search for the given process. This would entail dispatching that task periodically to check on status.
Alternatively, one could write a mex routine using system API calls to do this internally from Matlab or perhaps someone has already done it -- might search on the File Exchange to see. There are bound to be other system monitor routines available that could be used but I've not looked for any specifically.
ADDENDUM
It wouldn't be too hard to wrap the CMD TASKLIST utility in an m-file as a rudimentary tool to accomplish the goal...
function isfound=istaskrunning(task)
% returns TRUE if executable image name is found and status running
% SYNTAX:
% logicalResult = istaskrunning(TASK)
% returns T for if TASK input as string presently running
%
cmd = sprintf('tasklist /FI "IMAGENAME eq %s" /FI "STATUS eq running"',task);
[stat,res]=system(cmd);
isfound=~isempty(strfind(lower(res),lower(task)));
Sample use...
>> task='matlab.exe'; % is a matlab session running?
>> istaskrunning(task) % result of query is True (yes)
ans =
1
>> istaskrunning('junk.bat') % try something know isn't extant
ans =
0
and the latter is False as should be.
You can do more sophisticated searches including a PID for a specific process or the window title if you were to start each process with a unique title besides just the executable name in order to identify the specific instances you're after.

8 Comments

"Win32 programs don't have a console"
?? As far as I know, Win32 programs can execute in console context or can detach themselves as graphics applications that return immediately after initialization.
dpb
dpb on 28 Sep 2017
Edited: dpb on 28 Sep 2017
CAN is the key there; most Win32 programs are fully graphic/GUI only that don't have the text console...that appears to be OP's problem in that he gets no results from the app via stdout; whatever output it has goes to whatever gui widgets there are or files...
One can build text-based apps that run under Windows, yes, and one can open a console window under program control with a primarily graphics app but most don't...
Joao
Joao on 4 Oct 2017
Edited: Joao on 4 Oct 2017
Hi dpb!
Thanks for you answer! I followed your advice and implemented the istaskrunning function to solve my problem! But unfortunatly it didn't and I don't manage to understand why. So it seems to work great for programs installed on my system (Matlab, drobox, chrome...) but it doesn't work for an standalone exe file. I always get the answer 0. Do you have any idea why is that? I have several folders with information that a executable file containing some fortran code will read and process. Because I want to use several cores to speed up my calculations, it would be great to know when each executable file stopped working so I could execute another one.
Can't read tiny images; what are they supposed to tell us?
Probably you're not matching the actual task name or somesuch other reason--can't tell without being able to see first the function as you implemented it, how it is being used and what commands were used to initiate the task and try to find it in the task list. Or, possibly, the task is so short-lived that by the time you dispatch the look for it task, it's already completed???
ADDENDUM
After blowing up screen 250% I can just barely make out the lettering; looks to me like the executable name begins with an 'm' while your search string starts with 'n' but the images are awfully blurry owing to having to expand them so much...
That the executable is 'mo' something seems certain based on alphabetical ordering in the tasklist; what the initial character in the command window is is not possible to determine exactly owing to resolution but surely as above looks to me like an 'n' instead.
Also, that line is cut off so can't see whole thing; it appears the actual image has a '*32' appended to the .exe; if that is so it needs to be in the search string which we can't see what was in its entirety. Or, is that some figment later releases of Windows have added to the taskslist display that isn't real--that I don't know but the task and the description aren't the same in the two columns and you need to match the task name exactly by the search you're doing not the description.
Why don't you create some much shorter and user-friendly names for the executables and/or use a unique window title or the like to simplify life?
ADDENDUM
OBTW, you can use the '*' wildcard in the task name...try something like
*water*
for the task name and see what you get...should be the list of all and would clarify above questions/uncertainties.
Also, it looks like the image names are all the same so you can't distinguish one from another by that alone--you will have to either retrieve a PID or use a window name or some other ID to tell which is which.
Joao
Joao on 4 Oct 2017
Edited: Joao on 4 Oct 2017
Thanks for your reply! Sorry for the quality of the image. It was supposed to show that although I had 3 instances of the executable running it doesn't show up in tasklist. The image name is correct, I've tried with only one instance running, the *32 is not real in the name, I've tested with a simple name, I've tried with other wildcards as you suggested. Nothing works. Losing all hope here!
ADDENDUM
Regarding the function is a copy paste from your post above. I'm using it directly just defining task like you shown in the example. I've also tried directly in the cmd line with no luck.
Ah! I now see you're looking at "Processes" tab, not "Applications". It appears that MOHID Suite spawns the threads; if you look at the Applications tab those don't show up, do they? If not, the above won't find them; you'll have to delve deeper into the Win32 API to retrieve that info by connecting to the main process and querying its children.
I'm not sure that TASKLIST can do that; I'd have to dig into it in more detail and I've got meetings in town at the moment so will have to run....it'll be late evening at earliest before I can get back, sorry...
Thank you so much for your help. I'm actually come to a workaround that I still need to test. I'm outputting the result form the executable to a file and read it to detect if it is still running or not, and them based on the outputs if it got an error or not. It will increase some time to the computation but I think it is the more robust way of doing this. Again thank you for your time!
Well, it's undoubtedly do-able; Jan looked into Java as way to get to the internals of the OS APIs; I don't know much about that for where to get the doc to look it up so let him go that route...
I'm curious about the result of the above, however, what do you see at the Applications level instead of Processes? Was/Is my supposition correct in that regards?

Sign in to comment.

Jan
Jan on 4 Oct 2017
Edited: Jan on 30 Dec 2020
exeFile = 'c:\temp\example.exe';
startInfo = System.Diagnostics.ProcessStartInfo('cmd.exe', ...
sprintf('/c "%s"', exeFile));
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
proc = System.Diagnostics.Process.Start(startInfo);
if isempty(proc)
error('Failed to launch process');
end
while true
if proc.HasExited
fprintf('\nProcess exited with status %d\n', proc.ExitCode);
break
end
fprintf('.');
pause(1.0);
end
Does this help?
Or through Java:
exeFile = 'c:\temp\example.bat';
cmd = sprintf('cmd.exe /c "%s"', exeFile);
runtime = java.lang.Runtime.getRuntime();
proc = runtime.exec(cmd);
% a = proc.getInputStream;
% b = proc.getOutputStream;
while true
% a.read; % Causes a stall on my machine?!
% b.flush;
try
exitCode = proc.exitValue();
fprintf('\nProcess exited with status %d\n', exitCode);
break;
catch
err = lasterror(); % old syntax for compatibility
if strfind(err.message, 'process has not exited')
fprintf('.');
pause(.1);
else
rethrow(err);
end
end
end
Or
runtime = java.lang.Runtime.getRuntime();
process = runtime.exec('program arg1 arg2'); % non-blocking
% rc = process.waitFor(); % block Matlab until external program ends
% rc = process.exitValue(); % fetch an ended process' return code
% process.destroy(); % Kill process prematurely

3 Comments

Joao
Joao on 7 Nov 2017
Edited: Joao on 7 Nov 2017
Hi Jan,
Sorry to only now get back at you, but I was implementing a different approach, in which I wrote the output from the executable and looked for a successful finished message. This was working great when the executable run correctly but not that much when there is an error. When an error occurs there are a lot of possibilites thus realistically expect to be able to catch them all is a shoot in the dark. What brings me back to this topic. I've tried your approach through Matlab and when testing (just stopping the executable) I got a exit message status 1. How can I decipher this status? Also in your approach matlab gets busy until the executable is running. Is there a possibility to use something like system('start /MIN Mohid.exe') a leave Matlab continue with the script. As I mentioned above the main goal is to detect which simulations finished (correctly/error) and replace them by new ones, and this on the go. I've several millions to do, and a limited number of cores.
UPDATE: Just tested a successful run of the executable and the status is the same as when an error occurs (Status 0). Status 1 is shown when I close directly the window. Not sure if I'm doing something wrong here.
Thanks in advance
Joao
@Joao: Which of the three approaches I had posted do you mean? The first one blocks Matlab only, because the "while true" loop runs until proc.HasExited is true. Of course you can omit this loop and check the status anywhere else. The last method is also non-blocking.
Is there a possibility to use something like
system('start /MIN Mohid.exe')
Perhaps, but then there is no way to check reliably, if the functions have finished correctly. Therefore I'd prefer either the java runtime.exec or the .NET Process.Start.
I do not understand the detail about the status. Where is what shown and what is the problem?
Joao
Joao on 9 Nov 2017
Edited: Joao on 9 Nov 2017
Jan, thanks for your reply. I was mentioning your first approach. I solved the problem by using the CMD command 2> to export the result of the possible errors occurring when running the executable. I've manage to simplify the code because when the CMD window closes if the file generated is empty the executable ran successfully otherwise it will produce an output which is the error.

Sign in to comment.

Categories

Tags

Asked:

on 28 Sep 2017

Edited:

Jan
on 30 Dec 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!