1

I finally discovered a way to use command line Matlab from .NET without linking:

  1. Write variables from .NET to a MAT file using David A. Zier's "csmatio" dll.

  2. Read the file from Matlab, process it and save the results to a MAT file:

    var process = new Process()
    {
        StartInfo = new ProcessStartInfo()
        {
            FileName = MatlabExecutableFileName,
            Arguments = "-nodisplay " + 
               "-nojvm " +
               " -r \"somecommands; " + 
               "save FILENAME OUTPUTVARIABLES; " +
               "exit;\""
        }
    };
    process.Start();
    
  3. The worst part: Wait until the process finishes.

    The naive approach:

    process.WaitForExit();
    

    Doesn't work because matlab spawns the main application in a new thread

    Watching for the output file for changes is tricky:

    new FileSystemWatcher(MatlabPath, fileName)
        .WaitForChanged(WatcherChangeTypes.All)
    

    Was not working because of a bug on this class.

    The currently working code is longer:

    using (var watcher = new FileSystemWatcher(MatlabPath, fileName))
    {
        var wait = new EventWaitHandle(false, EventResetMode.AutoReset);
        watcher.EnableRaisingEvents = true;
        watcher.Changed += delegate(object sender, FileSystemEventArgs e)
        {
           wait.Set();
        };
        foreach(var i in Enumerable.Range(0, 2))
        {
            if (!wait.WaitOne(MillissecondsTimeout))
            {
                throw new TimeoutException();
            }
        }
        Thread.Sleep(1000);
    }
    

    But I am concerned about the last line of code. The code block above was written with the intent of avoiding it, but I don't know what else to do. This amount of time will be too much on some computers and too little on others.

SOLUTION

var previousProcesses = Process
    .GetProcessesByName("Matlab")
    .Select(a => a.Id)
    .ToArray();
process.Start();
process.WaitForExit();
var currentProcess = Process
    .GetProcessesByName("Matlab")
    .Where(a => !previousProcesses.Contains(a.Id))
    .First();
currentProcess.WaitForExit();

4 Answers 4

3

A much better option is the -wait flag for matlab. It tells the matlab starter to terminate together with the main matlab process.

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

Comments

1
+150

Not sure if I completely understand the question (you're essentially trying to detect when the matlab process finishes right?), but couldn't you find matlab's main application process & wait for it to exit? i.e. something like this:

process.WaitForExit();  //only waits for the launcher process to finish
//but now matlab should be running in a new process...
var matlabProcess = Process.GetProcessesByName("whatever process is called");
//assuming only one matlab instance running...
//you'd probably want to write some defensive code here...
matlabProcess[0].WaitForExit();

Seems like that would be simpler than trying to watch it change files & guess when its finished...

Comments

0

How about determining the actual process for the separate thread and calling WaitForExit on it? Maybe use the command line program tasklist to get the PID's of all MATLAB processes and filter out the PID of the one you have.

Alternatively, there might be a .NET structure (probably related to process) which could return a child thread of process and wait for it.

Unfortunately, I don't know details, but it's worth a try searching that avenue.

Comments

0

I slightly changed the Solution so it worked for me

var previousProcesses = Process
   .GetProcessesByName("Matlab")
   .Select(a => a.Id)
   .ToArray();
var process = Process.Start(startInfo);
process.WaitForExit();
var newProcessRunning = Process
   .GetProcessesByName("Matlab")
   .Where(a => !previousProcesses.Contains(a.Id));
if (newProcessRunning.Count() != 0)
   newProcessRunning.First().WaitForExit();

Comments

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.