[C#] Process.Startを利用して外部アプリケーション起動後に非同期でプロセス終了を検知する方法


はじめに

あるアプリケーションから外部アプリケーションを起動する際によく利用するのが、「Process.Start」メソッドだと思います。

同期的にプロセスの終了を検知する場合は、「Process.WaitForExit」を利用します。

しかし、WaitForExitを利用してしますと、起動したアプリケーションのプロセスが終了するまで起動元アプリケーションの処理をすることができなくなってしまいます。

今回は、外部アプリケーションを起動後に同期的に処理終了を待つのではなく、非同期で処理が終了したことを検知する方法の備忘録です。

プロセス終了を待機する (WaitForExit利用)

まずは非同期での検知ではなく、プロセス終了を待機する方法です。

var psi = new ProcessStartInfo();
psi.UseShellExecute = true;
psi.FileName = "TestApplication.exe";
psi.ErrorDialog = true;

try
{
    var proc = Process.Start(psi);

    // 無制限で終了を待つ場合は引数なし
    proc.WaitForExit();

    // 10秒待機する場合は下記のように引数を指定(ミリ秒)
    // proc.WaitForExit(10000);

    Console.WriteLine("$HasExited Status is {proc.HasExited}"); 
}
catch
{
    Console.WriteLine("Exception error occured.");
}

HasExitedにて終了状態を取得しています。ここでは「True」が出力されるはずです。(正常動作)

コメントアウトしていますが、最大で〜ミリ秒待機するように指定可能です(ここでは10秒に指定しています)

用途に応じて設定してください。

非同期にプロセス終了を検知する (Process.Exitedイベント)

プロセスが終了した時にProcess.Exitedイベントを発生させます。

Process.Exited イベント

public void Test()
{
    var psi = new ProcessStartInfo();
    psi.UseShellExecute = true;
    psi.FileName = "TestApplication.exe";
    psi.ErrorDialog = true;

    try
    {
        var proc = Process.Start(psi);

        proc.EnableRaisingEvents = true;
        // Event Handler登録
        proc.Exited += new EventHandler(Proc_Exited);

        Console.WriteLine("$HasExited Status is {proc.HasExited}"); 
    }
    catch
    {
        Console.WriteLine("Exception error occured.");
    }
}

private void Proc_Exited(object sender, EventArgs e)
{
    var proc = (Process)sender;
    Console.WriteLine("$HasExited Status is {proc.HasExited} (Exited Event)");  
}

まず、EnableRaisingEventsはプロセスが終了した時にExitedイベントを発生させるかどうかの設定となります。(Process.EnableRaisingEvents プロパティ)

HasExitedにて終了状態を出力していますが、実行直後の出力では「False」が出力されるでしょう。

しかし、起動した外部アプリケーションを終了した場合、Proc_Exitedイベントにて終了検知した結果「True」として出力されます。

※ 再度同じ外部アプリケーションを呼び出した場合は、別プロセスとなるため同じプロセスに再接続することはできません、新しいプロセスとなります。

最後に

外部アプリケーションを呼び出す際、同期的に処理するか非同期で処理するかは設計したアプリケーションによります。

どちらも利用できるように備忘録として残しておきます。