への参照を取得したSystem.Diagnostics.Process
場合、プロセスが現在実行中かどうかを知るにはどうすればよいですか?
13 に答える
これは名前でそれを行う方法です:
Process[] pname = Process.GetProcessesByName("notepad");
if (pname.Length == 0)
MessageBox.Show("nothing");
else
MessageBox.Show("run");
すべてのプロセスをループして、後で操作するために ID を取得できます。
Process[] processlist = Process.GetProcesses();
foreach(Process theprocess in processlist){
Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
}
これは、リフレクターを使用した後に見つけた最も簡単な方法です。そのための拡張メソッドを作成しました。
public static class ProcessExtensions
{
public static bool IsRunning(this Process process)
{
if (process == null)
throw new ArgumentNullException("process");
try
{
Process.GetProcessById(process.Id);
}
catch (ArgumentException)
{
return false;
}
return true;
}
}
メソッドはメソッドをProcess.GetProcessById(processId)
呼び出し、プロセスが存在しない場合にProcessManager.IsProcessRunning(processId)
スローします。ArgumentException
何らかの理由で、ProcessManager
クラスは内部です...
同期ソリューション:
void DisplayProcessStatus(Process process)
{
process.Refresh(); // Important
if(process.HasExited)
{
Console.WriteLine("Exited.");
}
else
{
Console.WriteLine("Running.");
}
}
非同期ソリューション:
void RegisterProcessExit(Process process)
{
// NOTE there will be a race condition with the caller here
// how to fix it is left as an exercise
process.Exited += process_Exited;
}
static void process_Exited(object sender, EventArgs e)
{
Console.WriteLine("Process has exited.");
}
これはワンライナーである必要があります。
public static class ProcessHelpers {
public static bool IsRunning (string name) => Process.GetProcessesByName(name).Length > 0;
}
reshefm の回答はとても良かったです。ただし、プロセスが最初から開始されていない状況は考慮されていません。
これは、彼が投稿したものの修正版です。
public static bool IsRunning(this Process process)
{
try {Process.GetProcessById(process.Id);}
catch (InvalidOperationException) { return false; }
catch (ArgumentException){return false;}
return true;
}
彼の ArgumentNullException を削除しました。これは、実際には null 参照例外であると想定され、とにかくシステムによってスローされるためです。また、プロセスが最初から開始されていないか、close() メソッドを使用してプロセスを閉じる状況も説明しました。処理する。
これは、この機能をどの程度信頼できるものにしたいかによって異なります。あなたが持っている特定のプロセス インスタンスがまだ実行中であり、100% の精度で利用できるかどうかを知りたい場合は、運が悪いです。これは、マネージド プロセス オブジェクトからプロセスを識別する方法が 2 つしかないためです。
最初はプロセス ID です。残念ながら、プロセス ID は一意ではなく、再利用できます。プロセス リストで一致する ID を検索すると、同じ ID のプロセスが実行されていることがわかりますが、それは必ずしもあなたのプロセスではありません。
2 番目の項目はプロセス ハンドルです。ただし、ID と同じ問題があり、操作がより厄介です。
中レベルの信頼性を求めている場合は、現在のプロセス リストで同じ ID のプロセスを確認するだけで十分です。
Process.GetProcesses()
行く方法です。ただし、プロセスがどのように実行されているか (つまり、タイトルバーがあるかどうかにかかわらず、サービスまたは通常のアプリとして) に応じて、プロセスを見つけるために 1 つまたは複数の異なる基準を使用する必要がある場合があります。
必要なプロセスの Process インスタンスを 1 回インスタンス化し、その .NET Process オブジェクトを使用してプロセスを追跡し続けることができます (追跡していたプロセスが終了した場合でも、その .NET オブジェクトで明示的に Close を呼び出すまで追跡し続けます)。 [これは、プロセスのクローズ時間、別名 ExitTime などを提供できるようにするためのものです])
http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspxを引用:
関連するプロセスが終了すると (つまり、正常終了または異常終了によってオペレーティング システムによってシャットダウンされると)、システムはプロセスに関する管理情報を保存し、WaitForExit を呼び出したコンポーネントに戻ります。Process コンポーネントは、終了したプロセスへのハンドルを使用して、ExitTime を含む情報にアクセスできます。
関連付けられたプロセスが終了したため、コンポーネントの Handle プロパティは既存のプロセス リソースを指しなくなりました。代わりに、ハンドルは、プロセス リソースに関するオペレーティング システムの情報にアクセスするためだけに使用できます。システムは、Process コンポーネントによって解放されていない、終了したプロセスへのハンドルを認識しているため、Process コンポーネントが具体的にリソースを解放するまで、ExitTime および Handle 情報をメモリに保持します。このため、Process インスタンスに対して Start を呼び出すときはいつでも、関連付けられたプロセスが終了し、そのプロセスに関する管理情報が不要になったときに Close を呼び出します。Close は、終了したプロセスに割り当てられたメモリを解放します。
Coincoin のソリューションを試してみまし
た。ファイルを処理する前に、一時ファイルとしてコピーして開きます。
完了したら、アプリケーションがまだ開いている場合はアプリケーションを閉じ、一時ファイルを削除します。
プロセス変数を使用して、後で確認します。
private Process openApplication;
private void btnOpenFile_Click(object sender, EventArgs e) {
...
// copy current file to fileCache
...
// open fileCache with proper application
openApplication = System.Diagnostics.Process.Start( fileCache );
}
後でアプリケーションを閉じます:
...
openApplication.Refresh();
// close application if it is still open
if ( !openApplication.HasExited() ) {
openApplication.Kill();
}
// delete temporary file
System.IO.File.Delete( fileCache );
それは動作します(これまでのところ)
たぶん(おそらく)私は質問を間違って読んでいますが、Process オブジェクトによって表されるプロセスが終了したことを示す HasExited プロパティを探していますか(正常かどうか)。
参照先のプロセスに UI がある場合、Responding プロパティを使用して、UI が現在ユーザー入力に応答しているかどうかを判断できます。
ブロックする場合は、EnableRaisingEvents を設定して Exited イベント (非同期的に送信される) を処理するか、WaitForExit() を呼び出すこともできます。
プロセス ID による既存のプロセスのチェックに関して、.Net フレームワークからサポートされている API にもかかわらず、これらの関数は非常に低速です。Process.GetProcesses() または Process.GetProcessById/Name() を実行するには、大量の CPU サイクルが必要です。
実行中のプロセスを ID で確認するより迅速な方法は、ネイティブ API OpenProcess()を使用することです。戻りハンドルが 0 の場合、プロセスは存在しません。ハンドルが 0 以外の場合、プロセスは実行中です。許可があるため、この方法が常に 100% 機能するという保証はありません。