MATLABのプログラムを実行ファイルにしたとき,実行ファイルのパスを取得したい
37 views (last 30 days)
Show older comments
Yumi Iwakami
on 27 Feb 2018
Commented: Yumi Iwakami
on 28 Feb 2018
.mファイルで自分のいるパスを取得するとき,pwdを使って絶対パスを取得し,同じ階層に絶対パスでディレクトリを作成し,その中に処理したファイルを格納するようにプログラムを書いたのですが,MATLAB Compilerでファイルをコンパイルし,exeファイルにすると自分のいる(exeファイルのある場所)絶対パスを取得できないのですが,どうしたらいいでしょうか?
絶対パスの取得が無理なら相対パスでもいいのですが,exeと同じ階層にディレクトリを作り,その中に処理したファイルを格納する方法をご教示ください.
0 Comments
Accepted Answer
Kojiro Saito
on 27 Feb 2018
MATLAB Compilerでコンパイルしたexeファイルでも、pwdで絶対パスの取得はできます。 例えば、
function getPwd
out = pwd;
disp(out)
mkdir(out, 'result');
A = ones(1);
csvwrite(fullfile('result', 'A.csv'), A)
のような関数で、MATLAB Compilerのコンパイル時のオプションで「Windowsの実行コマンドシェルを表示しない」のチェックを外してexeを作成し、
コンパイル時に作成されるフォルダーfor_redistribution_files_only内にあるexeを実行すると、コマンドプロンプト上でpwdの表示(disp(out))が出力されます。(赤枠部分)
ただし、for_redistribution内にできるインストーラーのexe(MyAppInstaller_web.exe)からインストールすると、C:\Program Filesの中にexeがインストールされてしまいますが、ここのフォルダーには一般ユーザーでは書き込み権限が無く、MATLABのmkdirや結果ファイルの書き込みに失敗します。対応策としてはエクスプローラーでexeのインストールフォルダー(例えば、C:\Program Files\getPwd\application)を右クリックして「プロパティ」→セキュリティから一般ユーザーへの書き込み権限を追加することで回避できます。
ただ、Program Files内にデータを作成するのはセキュリティ的及びCドライブの容量的によろしくない場合があるので、、D:\Workのような別ドライブの別フォルダーに結果ファイルを出力するようにするのも手かもしれません。
More Answers (4)
Yumi Iwakami
on 27 Feb 2018
4 Comments
Kojiro Saito
on 27 Feb 2018
VBでGUIをボタンだけの作成して上記のgetPwd.exeを実行するプログラムを作ってみましたが、問題なくpwdの結果を取得でき、resultフォルダーを作成しA.csvも出力されました。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Run.Click
Dim RetVal
RetVal = Shell("getPwd")
End Sub
ですので、VBからMATLAB Compilerのexeを実行してもpwdは取得できているので、本件の原因はMATLABの処理の書き方にあるかもしれません、VB側のエラーにある、MATLABスクリプトの38行目では具体的にどのような処理を行っていますでしょうか?
Yumi Iwakami
on 28 Feb 2018
1 Comment
Kojiro Saito
on 28 Feb 2018
MATLAB Runtimeのキャッシュが悪さしているのかもしれません。
C:\Users\ユーザー名\AppData\Local\Temp\ユーザー名 の中にmcrCache9.3(R2017bの場合)やmcrCache9.2(R2017aの場合)というフォルダーがあるので、該当のMATLABバージョンに対応するRuntimeのキャッシュフォルダーを削除してからexeをダブルクリックで実行してみてもらえますでしょうか。
Yumi Iwakami
on 28 Feb 2018
Edited: Yumi Iwakami
on 28 Feb 2018
1 Comment
Kojiro Saito
on 28 Feb 2018
残るはVBからの呼び出しですね。VBのShellコマンドは非同期処理なので、MATLAB Compilerで作ったexeを起動した後、処理完了を待たずにVBの先の処理に進んでしまいます。
exeの処理が完了までVB側が待機するように、Shellコマンドではなく、WaitForExitを使ってみてはいかがでしょうか。
Imports System.Diagnostics
Sub Test()
Dim proc As New Process()
proc.StartInfo.FileName = "D:\testScript\ファイル名.exe"
proc.Start()
proc.WaitForExit()
End Sub
また、元のMATLAB関数でリターンを設定しても、exeにしてVBから実行するとリターンされるのはexeの成功か失敗かのフラグなので、もしMATLABからVB側に変数を返すようにしたいのでしたらMATLAB側で変数をファイルに書き込み、それをVB側で読み込むようにする必要があります。
Yumi Iwakami
on 28 Feb 2018
3 Comments
Kojiro Saito
on 28 Feb 2018
なるほどVBAでしたか。ExcelなどからVBAを実行していますか? その場合、カレントディレクトリがC:\Users\ユーザー名\Documents になっている可能性があります。 VBAのShellコマンド実行前にカレントディレクトリをexeと同じフォルダーに明示的に変更してみてはいかがでしょうか。
ChDrive "D:"
ChDir "D:\testScript"
また、VBAからexeを同期実行させる手段として、WshShellクラスを利用する方法もあります。
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!