I finally discovered a way to use command line Matlab from .NET without linking:
Write variables from .NET to a MAT file using David A. Zier's "csmatio" dll.
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();
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();