回答:
これは名前でそれを行う方法です:
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);
}
if/else
長さが1行しかないC#ステートメントでは、ブロックステートメントを示すために中括弧を付ける必要はありません。これはforeach
and for
ステートメントにも当てはまります。つまり、コーディングスタイルです。
for
。c#.net devの年と私はこのスタイルを見たことがありません。彼らが言うように、「あなたは毎日何か新しいことを学びます」。投稿と返信をありがとう..
これは、反射板を使用した後に見つけた最も簡単な方法です。そのための拡張メソッドを作成しました。
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.");
}
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つしかないためです。
1つ目はプロセスIDです。残念ながら、プロセスIDは一意ではなく、リサイクルできます。一致するIDのプロセスリストを検索すると、同じIDのプロセスが実行されていることがわかりますが、必ずしもプロセスとは限りません。
2番目の項目はプロセスハンドルです。Idと同じ問題がありますが、操作がより厄介です。
中程度の信頼性を求めている場合は、同じIDのプロセスについて現在のプロセスリストを確認するだけで十分です。
Process.GetProcesses()
行く方法です。ただし、プロセスの実行方法(タイトルバーの有無にかかわらず、サービスまたは通常のアプリとして)に応じて、プロセスを見つけるために1つ以上の異なる基準を使用する必要がある場合があります。
たぶん(おそらく)私は質問を間違って読んでいますが、Processオブジェクトによって表されるプロセスが終了したことを通知するHasExitedプロパティを探していますか(通常かどうかにかかわらず)。
参照しているプロセスにUIがある場合、Respondingプロパティを使用して、UIが現在ユーザー入力に応答しているかどうかを判断できます。
また、ブロックする場合は、EnableRaisingEventsを設定して、Exitedイベント(非同期に送信される)を処理するか、WaitForExit()を呼び出すこともできます。
必要なプロセスのプロセスインスタンスを1回インスタンス化し、その.NETプロセスオブジェクトを使用してプロセスを追跡し続けることができます(追跡していたプロセスが停止した場合でも、その.NETオブジェクトで明示的にCloseを呼び出すまで追跡し続けます) [これは、プロセスの終了時間、別名ExitTimeなどを提供できるようにするためです])
引用http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx:
関連するプロセスが終了すると(つまり、正常終了または異常終了によってオペレーティングシステムによってシャットダウンされると)、システムはプロセスに関する管理情報を格納し、WaitForExitを呼び出したコンポーネントに戻ります。次に、プロセスコンポーネントは、終了したプロセスへのハンドルを使用して、ExitTimeを含む情報にアクセスできます。
関連するプロセスが終了したため、コンポーネントのHandleプロパティは既存のプロセスリソースを指していません。代わりに、ハンドルは、プロセスリソースに関するオペレーティングシステムの情報にアクセスするためにのみ使用できます。システムは、プロセスコンポーネントによって解放されていない終了したプロセスへのハンドルを認識しているため、プロセスコンポーネントが具体的にリソースを解放するまで、メモリにExitTimeおよびHandle情報を保持します。このため、プロセスインスタンスに対してStartを呼び出すときはいつでも、関連するプロセスが終了し、それに関する管理情報が不要になったときに、Closeを呼び出します。Closeは、終了したプロセスに割り当てられたメモリを解放します。
私はコインコインの解決策を試しました:
ファイルを処理する前に、一時ファイルとしてコピーして開きます。
完了したら、アプリケーションがまだ開いている場合はアプリケーションを閉じ、一時ファイルを削除します
。Process変数を使用し、後で確認するだけです。
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 );
動作します(これまでのところ)
openApplication.HasExited()
、HasExitedは関数ではありません。正しい方法はでしょうopenApplication.HasExited
。
プロセスIDによる既存のプロセスのチェックに関して.NetフレームワークからサポートされているAPIにもかかわらず、これらの関数は非常に低速です。Process.GetProcesses()またはProcess.GetProcessById / Name()を実行するには、大量のCPUサイクルがかかります。
IDで実行中のプロセスを確認するより迅速な方法は、ネイティブAPI OpenProcess()を使用することです。リターンハンドルが0の場合、プロセスは存在しません。ハンドルが0以外の場合、プロセスは実行中です。許可を得ているため、このメソッドが常に100%機能するという保証はありません。
他にも部分的に対処しているように見えるため、これに関連する多くの問題があります。
他の人が言及したプロパティが内部であるかどうかにかかわらず、許可が許せば、リフレクションを介してそれらから情報を取得できます。
var x = obj.GetType().GetProperty("Name", BindingFlags.NonPublic | BindingFlags.Instance);
あなたはWin32コードをピンボークすることができます スナップショットのか、遅いWMIを使用できます。
HANDLE CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
別のオプションは、OpenProcess / CloseProcessですが、例外は以前と同じようにスローされますが、同じ問題が発生します。
WMIの場合-OnNewEvent.Properties ["?"]:
string process = "notepad";
if (Process.GetProcessesByName(process).Length == 0)
{
MessageBox.Show("Working");
}
else
{
MessageBox.Show("Not Working");
}
また、毎回プロセスをチェックするためにタイマーを使用することができます
length == 0
が表示されるはずですNot Working
)、それでもジョブは完了します。