Migaro. 技術Tips

                       

ミガロ. 製品の技術情報
IBMiの活用に役立つ情報を掲載!


【Delphi】別のEXEに引数を渡して実行する方法

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月号より)