Windows APIのCreateProcessを利用することで、
Delphiで作成したプログラムから別のプログラムを実行できます。
また、かつてはCreateProcessの2番目の引数に値を設定することで、
実行時引数を設定することが可能でした。
しかしWindowsのOSバージョンアップや、DelphiのUnicode対応などで
最近のバージョンでは当時のロジックが正しく動作しない場合がございます。
そこで今回は、CreateProcessを使って
Windows 10以上 かつ Delphi/400 10.2 Tokyoや11 Alexandriaでも有効な
引数ありの別EXEを呼び出す場合の記述方法を紹介します。
別のEXEに引数を渡して実行する方法
以下の例では「メモ帳」を「C:\sample.txt」が開いた状態で起動します。
以前は実行ファイル名(第1パラメータ)にメモ帳のパスを、
実行時引数(第2パラメータ)に開くテキストのパスを記述しましたが、
これらをコマンドラインにまとめて記述します。
また、そのまま実行するとコマンドラインの最初の要素が失われて
正しく呼び出されないため、UniqueStringを使って
文字列の内部の参照カウントを保証させます。
例)
procedure TForm1.Button1Click(Sender: TObject); var bRet: Boolean; SI: TStartupInfo; PI: TProcessInformation; argString:string; // コマンドライン begin GetStartupInfo(SI); // コマンドライン argString:= '"notepad.exe" "C:\sample.txt"'; // 参照カウントを保証させる UniqueString(argString); bRet := CreateProcess( nil, // 実行ファイル名 PChar(argString), // 実行時引数 nil, nil, False, CREATE_DEFAULT_ERROR_MODE, nil, nil, SI, PI ); // エラー確認 if not bRet then begin //起動に失敗したら例外を作成 raise Exception.Create('Exec Error ' + IntToStr(GetLastError)); end; end;
※実行時引数を使用しない場合は、従来通り実行ファイル名に実行ファイルのパスを指定可能です。
※それぞれ ” ” で囲んであるのは、
パスや引数にスペース文字が入っていた際に区切られないようにする対策です。
呼び出すファイル名や実行時引数にUnicode依存文字が含まれない場合には、
UniqueStringを使用せずに、CreateProcessではなく
Ansi版の関数CreateProcessAを呼び出すことでも対応可能です。
(この場合、TStartupInfoやGetStartupInfoにも末尾にAを付ける必要がある他、
PChar・StringはそれぞれPAnsiChar・AnsiStringに変更が必要です。)
Delphi/400で実行時引数を受け取る方法
次に、その引数を受け取る方法をご紹介いたします。
受け取り側のParamCount変数には、実行時引数のパラメータ数が設定されます。
また実行時引数はParamStr配列に格納されておりますので、
以下のようにして取得することが可能です。
// フォーム作成イベント procedure TForm1.FormCreate(Sender: TObject); var i :integer; begin if ParamCount > 0 then begin // 受け取ったパラメータをリストボックスに追加 for i := 1 to ParamCount do begin ListBox1.Items.Add(ParamStr(i)); end; end; end;
※ParamStrは1始まりです。『ParamStr(0)』を参照すると、
アプリケーションが実行されているファイルパス(Application.Exenameと同じ)が返ります。
呼び出したアプリケーションから終了コードを取得する方法については、
以前のこちらのTipsをご参照ください。
(呼出:ミガロ.情報マガジン「MIGARO News!!」Vol.127 2011年6月号より)
(受取:ミガロ.情報マガジン「MIGARO News!!」Vol.128 2011年7月号より)