PR

[C# Process]外部アプリを起動する(待機もするよ)

この記事では外部アプリを起動する方法、終了を待機する方法を紹介します。
C#のプログラムから他のアプリケーションを起動するには、名前空間System.DiagnosticsにあるProcessクラスを使います。また、StartInfoプロパティを使ってアプリを起動する際のパラメータを細かく指定することもできます。

スポンサーリンク

起動するだけの場合

他のアプリを起動するだけ(他アプリの終了を待たない)ならProcessクラスの静的メソッド(static)のStartメソッドを使うと簡単です。

using System.Diagnostics;

namespace TestProject;
class Program {
    static void Main(string[] args)
    {
        //メモ帳を起動
        Process.Start("notepad");

        //メモ帳に開きたいファイルパスを渡して起動
        Process.Start("notepad", "test.txt");
    }
}

第1引数に起動したいアプリケーションのファイルパス(フルパスやプログラムからの相対パス)を指定します。
外部アプリに引数を渡したい場合は第2引数を指定します。
引数を複数渡したい場合は半角スペースで区切って指定します。引数自体にスペースがある場合は文字列型の配列に入れて渡すとエスケープ文字を使って書かなくていいので簡単です。

//引数を複数渡したい場合は半角スペースで区切る
Process.Start("test.exe", "param1 param2");

//引数にスペースがある場合は配列に入れて渡すと簡単
Process.Start("test.exe", new string[] { "param1", "p a r a m 2" });
スポンサーリンク

起動して終了するまで待機する場合

外部アプリを起動して終了するまで待機するには、ProcessクラスのインスタンスにあるWaitForExitメソッドを使います。起動する外部アプリの情報はProcessクラスのStartInfoプロパティに設定します。

Startメソッドで外部アプリを起動し、WaitForExitメソッドで外部アプリが終了するまで待機(プログラムがストップ)します。

また、起動したアプリの終了の待機後、ExitCodeプロパティから終了コードを取得できます。これを使って起動したアプリがちゃんと動いたか判定することができます。

GUI(デスクトップアプリ)から外部アプリを起動する場合でプログラムを止めたくない(画面をフリーズさせない)時は後述の非同期で待機する場合を見てください。

using System.Diagnostics;

namespace TestProject;
class Program {
    static void Main(string[] args)
    {
        //Processクラスのインスタンスを作成
        using Process proc = new Process();
        //起動したい外部アプリの情報を設定
        proc.StartInfo.FileName = "notepad";    //起動したい実行ファイルのパス
        proc.StartInfo.Arguments = "";          //起動したい実行ファイルに渡すパラメータ
        //外部アプリ起動
        proc.Start();
        //外部アプリの終了を待機する
        proc.WaitForExit();

        //外部アプリの終了コードを表示
        Console.WriteLine(proc.ExitCode);
    }
}
スポンサーリンク

起動して終了するまで非同期で待機する場合

ProcessクラスにあるWaitForExitAsyncメソッドを使うと外部アプリの終了待機を非同期で行うことができます。このメソッドはデスクトップアプリで外部アプリの終了待機中に画面がフリーズしないようにするのに使えます。

サンプルとして、画面のボタンがクリックされるとメモ帳が起動され、メモ帳が開いている最中は画面のボタンが無効化され押せなくなり、メモ帳が閉じられるとボタンが有効化され押せるようになるというものを作ってみました。

以下のコードのbtnStart_Clickメソッドは画面のボタンがクリックされたときに呼ばれるメソッドの抜粋です。メソッド内でawaitというキーワードを使っているので、メソッドのシグネチャにasyncというキーワードを付けて非同期メソッドになっています。
14行目「await proc.WaitForExitAsync」のところで一旦制御が呼び出し元に戻ってくるので画面がフリーズすることがなくなります。外部アプリが終了すると次の行(17行目)から処理が再開されます。

using System.Diagnostics;
//-- 中略 --//
private async void btnStart_Click(object sender, RoutedEventArgs e)
{
    //ボタンを無効化
    this.btnStart.IsEnabled = false;

    //Processのインスタンスを作成して外部アプリの情報を設定して起動
    using Process proc = new Process();
    proc.StartInfo.FileName = "notepad.exe";
    proc.Start();

    //外部アプリの終了を非同期で待機
    await proc.WaitForExitAsync();

    //ボタンを有効化
    this.btnStart.IsEnabled = true;
}

非同期メソッドについてはこちらの記事で詳しく紹介しています。

[C#]非同期メソッドの使い方 -Taskをawaitするasyncなメソッドです-
今回は非同期処理についてです。なんかかっこいい響きですよね。ボタンをクリックしたら処理に時間がかかって画面が固まったことはありますか?1つの処理で時間がかかる場合、その処理が完了するまで画面がフリーズして(応答しなくなって)しまいます。そん...

Mainメソッドでも非同期っぽく

Mainメソッドでも外部アプリの終了を待機しつつ他の処理をしたい、という場合はStartメソッドとWaitForExitメソッドの間に処理を書くとそれっぽくなります。
正確には外部アプリ起動後になんか処理をしてから外部アプリを終了を待つという感じです。

using System.Diagnostics;

namespace TestProject;
class Program {
    static void Main(string[] args)
    {
        //Processクラスのインスタンスを作成
        using Process proc = new Process();
        //起動したい外部アプリの情報を設定
        proc.StartInfo.FileName = "notepad";    //起動したい実行ファイルのパス
        proc.StartInfo.Arguments = "";          //起動したい実行ファイルに渡すパラメータ
        //外部アプリ起動
        proc.Start();

        //-- ここに待機する前にやる処理を書く

        //外部アプリの終了を待機する
        proc.WaitForExit();
        //外部アプリの終了コードを表示
        Console.WriteLine(proc.ExitCode);
    }
}
スポンサーリンク

コンソールアプリ起動時にコンソール画面を非表示にする

デフォルトの設定でデスクトップアプリからコンソールアプリを起動するとコンソール画面(黒い画面)が表示されます。
これを表示しないようにするにはProcessクラスのStartInfoプロパティのCreateNoWindowプロパティをtrueに設定します。

private async void btnStart_Click(object sender, RoutedEventArgs e)
{
    //ボタンを無効化
    this.btnStart.IsEnabled = false;

    //Processのインスタンスを作成して外部アプリの情報を設定して起動
    using Process proc = new Process();
    proc.StartInfo.FileName = "test.exe";
    proc.StartInfo.CreateNoWindow = true;  //コンソール画面を表示しない
    proc.Start();

    //外部アプリの終了を非同期で待機
    await proc.WaitForExitAsync();

    //ボタンを有効化
    this.btnStart.IsEnabled = true;
}

StartInfoプロパティには他にもいろいろな項目があります。気になる方はMisrosoft公式ページを見てください。

ProcessStartInfo クラス (System.Diagnostics)
プロセスを起動するときに使用する値のセットを指定します。

C# 記事まとめページに戻る(他のサンプルコードもこちら)

C# プログラミング講座
C#についての記事まとめページです。開発環境VisualStudioのインストール方法や使い方、プログラミングの基礎知識についてや用語説明の記事一覧になっています。講座の記事にはすぐに実行できるようにサンプルコードを載せています。

コメント