8

I want to execute a batch file in dos from MATLAB and have control returned immediately to MATLAB. However, I want to do this without opening up a dos window (or, at the very least, get the dos window to disappear at the end).

If I format my command like this...

s = dos('batchfilename.bat');

then MATLAB runs the batch file without opening up a dos window, but the MATLAB code has to wait for the return.

If I format my command like this...

s = dos('batchfilename.bat &');

Control is returned immediately to MATLAB, but it also displays the dos window, which I don't want. (It's also difficult to detect when the batch file is "done" when you do it this way)

Any help would be appreciated.

2
  • 1
    @Jonas: You might have linked the wrong answer? That one has nothing to do with child processes. Commented Jan 19, 2012 at 18:39
  • @BenVoigt: sorry - right answer, wrong question :) Commented Jan 19, 2012 at 19:18

2 Answers 2

9

Use Matlab's External Interfaces support to get access to a lower level language's process control features.

.NET Version

Use the .NET System.Diagnostics.Process class. It'll let you run a process asynchronously, check for when it's exited, and collect the exit code. And you can optionally hide its window or leave it visible for debugging.

You can call .NET classes directly from M-code.

function launch_a_bat_file()
%//LAUNCH_A_BAT_FYLE Run a bat file with asynchronous process control

batFile = 'c:\temp\example.bat';
startInfo = System.Diagnostics.ProcessStartInfo('cmd.exe', sprintf('/c "%s"', batFile));
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;  %// if you want it invisible
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);
end

Java Version

The .NET version requires a Matlab new enough to have .NET support. Here's a Java-based version for older Matlabs, like OP turns out to have. Should also work on non-Windows systems with a bit of modification.

function launch_a_bat_file_with_java
%LAUNCH_A_BAT_FILE_WITH_JAVA  Java-based version for old Matlab versions

batFile = 'c:\temp\example.bat';
cmd = sprintf('cmd.exe /c "%s"', batFile);
runtime = java.lang.Runtime.getRuntime();
proc = runtime.exec(cmd);

while true
    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

You may need to fiddle with the I/O in the Java version to avoid hanging the launched process; demarcmj notes that you need to read and flush the Process's input stream for stdout to avoid it filling up.

Sign up to request clarification or add additional context in comments.

10 Comments

I get "Undefined variable "System" or class "System.Diagnostics.ProcessStartInfo". I must not have .NET installed on this machine. Which is a bummer, because this looked promising :( I'm gonna mark this as my accepted answer though, because I just tried this on my own computer and it worked great (I just can't use it on the computer I need to use it on)
Is there a minimum Version of MATLAB that that works with? I just looked and the computer it's not working on has .NET 3.5 which should be good enough. It's only got MATLAB 7.1.0.246 R14 though, which is a little old.
Works on R2009b for me. Matlab 7.1 is ancient; that's from mid 2005. .NET 2.0 hadn't even been released at that point. There's been a lot of work on Matlab's External Interfaces (which .NET support is part of) and a whole new OOP system since then. You should consider upgrading. Half the other answers on SO probably won't work on 7.1 either.
Unfortunately upgrading isn't an option. Guess I'll just have to add a button to my GUI to make progress indications an on-demand thing. It's not ideal, but it's the best I can do with what I'm given.
In case anyone is reading this in the future... Apparently, the proc object has buffered input and output streams that may fill up if you don't pay any attention to them, which causes the problem of hanging forever in Runtime.exec(). To prevent this, I needed to add "a = proc.getInputStream;" and "b = getOutputStream;" above the "while" and "a.read;b.flush;" below the "while" (at the beginning of each while loop iteration).
|
3

Try using the start cmdlet bundled with the Windows Command Interpreter.

You can probably do just system('start /MIN batchfilename.bat');

Put an exit command at the end of the batch file to make sure you aren't left with a (minimized) command prompt.

4 Comments

That might work (I'll have to give it a try and report back). I do see a potential flaw in that it doesn't give you the return value.
@demarcmj: Umm, there IS no exit code when system returns, since your MatLab code continues running without waiting for the child process. Actually you can get the return code from start, which may tell you if the batch file wasn't found. If you want to spawn a child and later query it for completion and exit code, you'll probably need to use MEX and some Win32 API functions such as CreateProcess.
In that case, I may just have to use the "s = dos('batchfilename.bat');" form so I get the proper return value, since I need that and don't want to mess around with any of that other stuff you were talking about at the end there. I guess my only way to "do stuff" while it is executing will be to add a separate button in my GUI, which isn't ideal but will get the job done.
You can also use .NET's System.Diagnostics.Process, called directly from M-code. Probably easier to code against than CreateProcess in a MEX, and it exposes ExitCode. msdn.microsoft.com/en-us/library/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.