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

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

採用された回答

Kojiro Saito
Kojiro Saito 2018 年 2 月 27 日
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 件のコメント
Yumi Iwakami
Yumi Iwakami 2018 年 2 月 27 日
回答ありがとうございます.
GUIはVBで作っていて,VBのShellコマンドでexeを呼び出しているので,MATLAB Compilerではなくmccコマンドでコンパイルしているのですが,MATLAB Compilerで作ることは可能なのでしょうか?

サインインしてコメントする。

その他の回答 (4 件)

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

サインインしてコメントする。


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

サインインしてコメントする。


Yumi Iwakami
Yumi Iwakami 2018 年 2 月 28 日
編集済み: Yumi Iwakami 2018 年 2 月 28 日
ご対応ありがとうございます.お示しいただいたフォルダの削除でMATLABは正常動作しました. exeのダブルクリックでMATLABのスクリプトは正常動作し,終了できました. しかし,依然として,VBからの呼び出しと,32行目でエラーで止まってしまいます. VBでは,以下のように書くことでMATLABのウィンドウにフォーカスをあてることはできました.
Sub Test()
Call Shell("D:\testScript\ファイル名.exe",vbNormalNoFocus)
End Sub
  1 件のコメント
Kojiro Saito
Kojiro Saito 2018 年 2 月 28 日
残るは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
Yumi Iwakami 2018 年 2 月 28 日
VBAを使っているのでProcessクラスがなく,Do-Loopでプロセスをまつ方法をとりましたが,やはり同じ行でエラーが出ます.
MATLABから値を渡したいのではなく,MATLABで画像の処理をまとめて行い,別の値をVBAのGUIで別の研究者が開発しています.
  3 件のコメント
Kojiro Saito
Kojiro Saito 2018 年 2 月 28 日
なるほどVBAでしたか。ExcelなどからVBAを実行していますか? その場合、カレントディレクトリがC:\Users\ユーザー名\Documents になっている可能性があります。 VBAのShellコマンド実行前にカレントディレクトリをexeと同じフォルダーに明示的に変更してみてはいかがでしょうか。
ChDrive "D:"
ChDir "D:\testScript"
また、VBAからexeを同期実行させる手段として、WshShellクラスを利用する方法もあります。
Yumi Iwakami
Yumi Iwakami 2018 年 2 月 28 日
上記のカレントディレクトリを明示的に指定する方法で解決しました.
いろいろとお教えいただき感謝いたします. ありがとうございました.

サインインしてコメントする。

カテゴリ

Help Center および File Exchange入力引数と出力引数 についてさらに検索

Community Treasure Hunt

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

Start Hunting!