MATLABのプログ​ラムを実行ファイルに​したとき,実行ファイ​ルのパスを取得したい

37 views (last 30 days)
Yumi Iwakami
Yumi Iwakami on 27 Feb 2018
Commented: Yumi Iwakami on 28 Feb 2018
.mファイルで自分のいるパスを取得するとき,pwdを使って絶対パスを取得し,同じ階層に絶対パスでディレクトリを作成し,その中に処理したファイルを格納するようにプログラムを書いたのですが,MATLAB Compilerでファイルをコンパイルし,exeファイルにすると自分のいる(exeファイルのある場所)絶対パスを取得できないのですが,どうしたらいいでしょうか?
絶対パスの取得が無理なら相対パスでもいいのですが,exeと同じ階層にディレクトリを作り,その中に処理したファイルを格納する方法をご教示ください.

Accepted Answer

Kojiro Saito
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のような別ドライブの別フォルダーに結果ファイルを出力するようにするのも手かもしれません。
  1 Comment
Yumi Iwakami
Yumi Iwakami on 27 Feb 2018
回答ありがとうございます.
GUIはVBで作っていて,VBのShellコマンドでexeを呼び出しているので,MATLAB Compilerではなくmccコマンドでコンパイルしているのですが,MATLAB Compilerで作ることは可能なのでしょうか?

Sign in to comment.

More Answers (4)

Yumi Iwakami
Yumi Iwakami on 27 Feb 2018
MATLAB Compilerのアプリケーションコンパイラでも試しましたが,やはりpwd絶対パスが取得できず, VBのShellコマンドでは読み込みファイルのあるディレクトリ(exeと同じ階層にあるディレクトリ)が取得できないためエラーが出て停止してしまいます.
pwdで絶対パスが取得できていないと判断している理由はpwdの代わりに文字列として固定の絶対パス(例えばC:\workなど)を指定してそのディレクトリに読み取りファイルのあるディレクトリ(例えばC:\work\id001)を置くと正常に処理ができるからです.
  4 Comments
Kojiro Saito
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
Yumi Iwakami on 28 Feb 2018
検証ありがとうございます.
エラーの該当行は別の関数にpwdで取得したパスをわたし,渡されたパスからファイルを参照してファイルの中のデータを読み取っています. 出ているエラーを見るとファイルが読み取れず,計算ができなくてでているのではないかと想定しています.
MATLAB上で実行すると,エラーは出ず,最後まで処理が行われること,pwdのところをカレントディレクトリのパスの文字列に変えるとexeに変換してもうまくいくことから,パスの参照ができていないと推測しています.

Sign in to comment.


Yumi Iwakami
Yumi Iwakami on 28 Feb 2018
こんな実験もしてみました. pwdでディレクトリ取得後,Dispで画面に表示しようとしたところ,VBから呼び出しても,直接ダブルクリックでexeをよび出しても下記のエラーになってしまいます.
CurrentDir=pwd;
disp(CurrentDir);
  1 Comment
Kojiro Saito
Kojiro Saito on 28 Feb 2018
MATLAB Runtimeのキャッシュが悪さしているのかもしれません。
C:\Users\ユーザー名\AppData\Local\Temp\ユーザー名 の中にmcrCache9.3(R2017bの場合)やmcrCache9.2(R2017aの場合)というフォルダーがあるので、該当のMATLABバージョンに対応するRuntimeのキャッシュフォルダーを削除してからexeをダブルクリックで実行してみてもらえますでしょうか。

Sign in to comment.


Yumi Iwakami
Yumi Iwakami on 28 Feb 2018
Edited: Yumi Iwakami on 28 Feb 2018
ご対応ありがとうございます.お示しいただいたフォルダの削除でMATLABは正常動作しました. exeのダブルクリックでMATLABのスクリプトは正常動作し,終了できました. しかし,依然として,VBからの呼び出しと,32行目でエラーで止まってしまいます. VBでは,以下のように書くことでMATLABのウィンドウにフォーカスをあてることはできました.
Sub Test()
Call Shell("D:\testScript\ファイル名.exe",vbNormalNoFocus)
End Sub
  1 Comment
Kojiro Saito
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側で読み込むようにする必要があります。

Sign in to comment.


Yumi Iwakami
Yumi Iwakami on 28 Feb 2018
VBAを使っているのでProcessクラスがなく,Do-Loopでプロセスをまつ方法をとりましたが,やはり同じ行でエラーが出ます.
MATLABから値を渡したいのではなく,MATLABで画像の処理をまとめて行い,別の値をVBAのGUIで別の研究者が開発しています.
  3 Comments
Kojiro Saito
Kojiro Saito on 28 Feb 2018
なるほどVBAでしたか。ExcelなどからVBAを実行していますか? その場合、カレントディレクトリがC:\Users\ユーザー名\Documents になっている可能性があります。 VBAのShellコマンド実行前にカレントディレクトリをexeと同じフォルダーに明示的に変更してみてはいかがでしょうか。
ChDrive "D:"
ChDir "D:\testScript"
また、VBAからexeを同期実行させる手段として、WshShellクラスを利用する方法もあります。
Yumi Iwakami
Yumi Iwakami on 28 Feb 2018
上記のカレントディレクトリを明示的に指定する方法で解決しました.
いろいろとお教えいただき感謝いたします. ありがとうございました.

Sign in to comment.

Categories

Find more on 入力引数と出力引数 in Help Center and File Exchange

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!