プロセスを起動し、プロセスの起動を待ち、プロセスの終了を待つ(CreateProcess)~Delphiでお手軽プログラミング

プロセス[メモ帳]を起動し(CreateProcess)、プロセスの起動を待ち(WaitForInputIdle)、プロセスの終了を待つ(WaitForSingleObject) ~Delphiでお手軽プログラミング

ソースコードの記述

Delphiを起動し、メニューから「ファイル」⇒「新規作成」⇒「Windows VCLアプリケーション -Delphi(W)」 をクリックする。
TButtonとTMemoをドラッグ&ドロップして配置し、Button1をダブルクリックして以下のソースコードを入力します。

procedure TForm1.Button1Click(Sender: TObject);
var StartupInfo:TStartupInfo;
    ProcessInformation:TProcessInformation;
    RetVal:Cardinal;
    RetValBool:LongBool;
    pFileName:PChar;
    FileName:String;
begin
  Memo1.Lines.Clear;

  //メモ帳 の実行ファイル名
  FileName:='notepad.exe';
  pFileName:=@FileName[1];

  ZeroMemory(@StartupInfo,SizeOf(TStartupInfo));
  StartupInfo.cb:=SIzeOf(TStartupInfo);
  StartupInfo.dwFlags:=STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow:=SW_SHOW;

  //プロセスを起動する
  RetValBool:=CreateProcess(
    nil, pFileName,
    nil, nil, False,
    NORMAL_PRIORITY_CLASS, nil, nil,
    Startupinfo, ProcessInformation
  );
  if RetValBool=False then
  begin
    Memo1.Lines.Add( Filename+'の起動に失敗しました('+GetLastError.ToString+')' );
    Exit;
  end;

  //プロセスの起動を待つ
  repeat
    //指定プロセスがユーザー入力の待機状態になるまで、
    //又は指定タイムアウト時間が経過するまで待機する
    //戻り値
    //  0:待機が正常に行われた
    //  WAIT_TIMEOUT:タイムアウト時間が経過
    //  WAIT_FAILED :エラーが発生
    RetVal:=WaitForInputIdle(ProcessInformation.hProcess,100);
    application.ProcessMessages;
  until RetVal<>WAIT_TIMEOUT; //タイムアウト(100ms経過)ならループ

  if RetVal=WAIT_FAILED then
  begin
    Memo1.Lines.Add('起動待ちでエラー('+GetLastError.ToString+')');
    CloseHandle(ProcessInformation.hProcess);
    CloseHandle(ProcessInformation.hThread);
    Exit;
  end;
  Memo1.Lines.Add(Filename+'が起動しました');

  //プロセスの終了を待つ
  repeat
    //シグナル状態(終了状態)になるか
    //タイムアウト間隔が経過するまで待機する
    //戻り値
    //  WAIT_OBJECT_0:オブジェクトがシグナル状態になった
    //  WAIT_TIMEOUT:タイムアウト時間が経過
    //  WAIT_FAILED:エラーが発生
    RetVal:=WaitForSingleObject(ProcessInformation.hProcess,100);
    application.ProcessMessages;
  until RetVal<>>WAIT_TIMEOUT; //タイムアウト(100ms経過)しただけならループ

  if RetVal=WAIT_FAILED then
  begin
    Memo1.Lines.Add('終了待ちでエラー('+GetLastError.ToString+')');
  end
  else
  begin
    Memo1.Lines.Add(Filename+'が終了しました');
  end;

  CloseHandle(ProcessInformation.hProcess);
  CloseHandle(ProcessInformation.hThread);
end;

実行する

実行して「Button1」をクリックするとメモ帳が起動し「notepad.exeが起動しました」と表示され、メモ帳を終了すると「notepad.exeが終了しました」と表示されます。