C Sharpの応用 - 外部ソフトウェア
概要
外部ソフトウェアにおいて、実行ファイルを指定して起動する方法とファイルを関連付けられたソフトウェアで起動する方法を記載する。
また、外部ソフトウェアを起動して、そのソフトウェアが終了するまで待機する方法も記載する。
外部アプリケーションの起動
外部ソフトウェアを起動するには、起動する外部ソフトウェアのパスを指定して、ProcessクラスのStartメソッドを使用する。
以下の例では、メモ帳を起動している。
外部ソフトウェアが起動する時、Startメソッドはそのプロセスを表すProcessクラスを返す。
// メモ帳を起動する
var process = System.Diagnostics.Process.Start("notepad.exe");
ProcessクラスのStartメソッドの第2引数は、外部ソフトウェアを起動する時に使用するコマンドライン引数を指定する。
以下の例では、コマンドライン引数にテキストファイルのパスを指定してメモ帳を起動している。
// コマンドライン引数を指定してメモ帳を起動する
var process = System.Diagnostics.Process.Start("notepad.exe", @"C:\test\test.txt");
※注意
外部ソフトウェアが既に起動しており、そのプロセスが再利用された場合はnullを返す。
例えば、Windowsフォトビューアの実体は"dllhost.exe"であるが、これは、フォトビューアの起動の有無に関わらず実行され続けている。
そのため、ProcessクラスのStartメソッドでフォトビューアを起動する時、プロセスが再利用されてnullを返す。
ProcessStartInfoクラスを使用してProcess.Startメソッドを呼び出す
ProcessクラスのStartメソッドは、ProcessStartInfoクラスを指定して呼び出すこともできる。
この方法を使用することで、さらに高度な設定を行い、外部ソフトウェアを起動することができる。
以下の例では、メモ帳を起動している。
// ProcessStartInfoクラスを作成する
var ProcessInfo = new System.Diagnostics.ProcessStartInfo();
// 起動する実行ファイルのパスを設定する
ProcessInfo.FileName = "notepad.exe";
// 外部ソフトウェアを起動する
var Process = System.Diagnostics.Process.Start(psi);
コマンドライン引数を指定するには、ProcessStartInfoクラスのArgumentsプロパティを使用する。
以下の例では、コマンドライン引数にテキストファイルのパスを指定してメモ帳を起動している。
// ProcessStartInfoクラスを作成する
var ProcessInfo = new System.Diagnostics.ProcessStartInfo();
// 起動するファイルのパスを指定する
ProcessInfo.FileName = "notepad.exe";
// コマンドライン引数を指定する
ProcessInfo.Arguments = @"C:\test\test.txt";
// 外部ソフトウェアを起動する
System.Diagnostics.Process.Start(psi);
同期して待機する
ProcessクラスのWaitForExitメソッドを使用して、外部ソフトウェアが終了するまで待機することができる。
WaitForExitメソッドは同期して待機するため、待機中はフリーズしたようになる。
// メモ帳を起動して終了まで待機する
var process = System.Diagnostics.Process.Start("Notepad.exe");
process.WaitForExit();
引数に待機する最大時間をミリ秒単位で指定することができる。
指定した時間が経過した場合、プロセスが終了せずともWaitForExitメソッドが終了し、次の命令に処理が移る。
なお、プロセスの終了状態は、ProcessクラスのHasExitedプロパティで確認できる。
// ファイルを開く
var process = System.Diagnostics.Process.Start("Notepad.exe");
// 終了するまで10秒待機する
process.WaitForExit(10000);
// プロセスの終了状態を確認する
if (p.HasExited)
{
MessageBox.Show("終了しました。");
}
else
{
MessageBox.Show("終了していません。");
}
非同期で待機する
ProcessクラスのExitedイベントハンドラを使用して、非同期で待機することができる。
Exitedイベントハンドラは、ProcessクラスのEnableRaisingEventsプロパティがTrueの時のみ発生する。
ProcessクラスのExitedイベントハンドラは、何もしないと別スレッドで実行される。
そのため、マルチスレッドの知識が無いと危険であるが、ProcessクラスのSynchronizingObjectプロパティにフォームを設定することで、
そのフォームのスレッドでExitedイベントハンドラが実行されるため、安全に使用できる。
以下の例では、起動したメモ帳が閉じられるまで非同期で待機している。
ボタンを押下した場合はメモ帳を起動して、メモ帳が終了するとp_Exitedメソッドを呼び出す。
// Button1のClickイベントハンドラ
private void button1_Click(object sender, System.EventArgs e)
{
// Processオブジェクトを作成する
var process = new System.Diagnostics.Process();
// 起動するファイルを指定する
process.StartInfo.FileName = "notepad.exe";
// イベントハンドラがフォームを作成したスレッドで実行されるようにする
process.SynchronizingObject = this;
// イベントハンドラの追加
process.Exited += new EventHandler(p_Exited);
// プロセスが終了した時にExitedイベントを発生させる
process.EnableRaisingEvents = true;
// プロセスを起動する
process.Start();
}
private void p_Exited(object sender, EventArgs e)
{
// プロセスが終了したときに実行される
MessageBox.Show("終了しました。");
}
上記の例では、ソースコードの記述のみで全てを設定しているが、
Visual Studioのフォームデザイナにある[ツールボックス] - [コンポーネント] - [Process]をフォームに配置するだけで実現できる。