リンクせずに.NETからコマンドラインMatlabを使用する方法を最終的に発見しました:
David A. Zier の「csmatio」dll を使用して、.NET から MAT ファイルに変数を書き込みます。
Matlab からファイルを読み取り、処理して、結果を MAT ファイルに保存します。
var process = new Process() { StartInfo = new ProcessStartInfo() { FileName = MatlabExecutableFileName, Arguments = "-nodisplay " + "-nojvm " + " -r \"somecommands; " + "save FILENAME OUTPUTVARIABLES; " + "exit;\"" } }; process.Start();
最悪の部分:プロセスが終了するまで待ちます。
単純なアプローチ:
process.WaitForExit();
matlab が新しいスレッドでメイン アプリケーションを生成するため、機能しません
出力ファイルの変更を監視するのは注意が必要です。
new FileSystemWatcher(MatlabPath, fileName) .WaitForChanged(WatcherChangeTypes.All)
このクラスのバグのため、機能していませんでした。
現在動作しているコードはより長くなります:
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); }
しかし、コードの最後の行が気になります。上記のコード ブロックは、それを回避する目的で書かれていますが、他に何をすべきかわかりません。この時間は、一部のコンピューターでは長すぎ、他のコンピューターでは短すぎます。
解決
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();