Run Win32 executable and get status of completion...
Show older comments
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!!
Answers (2)
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
Walter Roberson
on 28 Sep 2017
"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.
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...
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.
dpb
on 4 Oct 2017
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...
Joao
on 4 Oct 2017
dpb
on 4 Oct 2017
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?
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
Jan
on 9 Nov 2017
@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?
Categories
Find more on Startup and Shutdown in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!