2008-11-04 111 views

回答

185

這是一種名爲做到這一點:

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); 
} 
+0

這正是我一直在尋找的。即使這是一個非常古老的帖子,你會向我解釋這是如何有效的C#。我不懷疑它,我認爲它有效,但我從來沒有見過沒有{}。 – MatthewD 2015-11-18 19:06:12

+2

@MatthewD:C#`只有一行的if/else`語句不需要用花括號來表示塊語句。這也適用於「foreach」和「for」語句。它歸結爲編碼風格。 – Hallmanac 2015-11-24 01:36:28

+0

我也對此進行了一些研究,發現信息,但我沒有看到「for」信息。多年的c#.net開發者和我從未見過這種風格。就像他們說的,「你每天都會學到新的東西」。謝謝你的帖子和回覆.. – MatthewD 2015-11-25 03:06:47

1

Process.GetProcesses()是要走的路。但是,您可能需要使用一個或多個不同的標準來查找您的流程,具體取決於它的運行方式(即作爲服務或普通應用程序,不管它是否具有標題欄)。

+0

如果您將此方法放在一個循環中,則會花費大量的CPU週期。我建議使用GetProcessByName()或GetProcessByID()。 – 2016-07-08 16:55:34

2

這取決於你想要這個功能的可靠程度。如果您想知道您擁有的特定流程實例是否仍在運行並且100%準確可用,那麼您的運氣不好。原因在於,從被管理的過程對象中,只有兩種方法可以識別過程。

第一個是進程ID。不幸的是,進程id不是唯一的,可以回收。在進程列表中搜索匹配的Id只會告訴你有一個進程使用相同的ID運行,但它不一定是你的進程。

第二項是過程句柄。它與Id一樣存在相同的問題,並且與其合作更加尷尬。

如果您正在尋找中等級別的可靠性,那麼檢查當前進程列表以找到具有相同ID的進程就足夠了。

0

也許(可能)我錯誤地閱讀了這個問題,但是您是否在尋找HasExited屬性,它會告訴您Process對象所代表的進程已經退出(通常與否)。

如果你的程序中有一個參考,以具有UI可以使用響應屬性來確定UI目前正對用戶輸入或沒有。

您還可以設置EnableRaisingEvents並處理Exited事件(它是異步發送的),或者如果您想阻塞,請調用WaitForExit()。

11

同步溶液:

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."); 
} 
+5

對於第一個選項:我怎麼知道這個過程是否是從第一個地方開始的? – reshefm 2008-11-06 11:39:31

22

這是我使用反射後發現的最簡單的方法。 我創建該擴展方法:

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類是內部的...

+0

這是一個非常好的答案;但是,您不應該通過參數null異常(因爲無論如何都會拋出null引用異常,並且您沒有對異常執行任何操作。而且,如果您沒有調用Start(),則會得到InvalidOperationException,或者你調用了close()方法,我發佈了另一個應答來解決這兩種情況 – Aelphaeis 2014-01-31 14:52:48

0

您可以爲您想要的進程實例化一次Process實例,並使用該.NET進程對象跟蹤進程(它會一直跟蹤,直到您調用Close該.NET對象顯式地,即使它正在跟蹤的進程已經死了[這是爲了能夠給你關閉進程的時間,也就是ExitTime等。])

引用http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx

當相關聯的處理退出(即,當通過正常或異常終止關閉由 操作系統),該系統對 存儲管理信息處理並返回到已調用WaitForExit的組件 。過程組件然後可以通過使用 句柄來訪問包含ExitTime的信息, Handle到退出的進程。

由於關聯進程已退出,因此 組件的Handle屬性不再指向現有的進程資源。相反, 句柄只能用於訪問有關進程資源的操作系統的 信息。系統知道處理 已退出進程組件, 尚未釋放的進程,因此它會將ExitTime和Handle信息保留在內存中,直到 進程組件專門釋放資源爲止。由於這個原因,當您調用Process實例的任何時候,您都可以撥打 ,當 關聯進程已終止,並且不再需要關於它的任何 管理信息時,請調用Close。關閉將分配給內存 的內存釋放到退出的進程。

0

我試圖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); 

它的工作原理(到目前爲止)

0
string process="notepad"; 
    if (Process.GetProcessesByName(process).Length == 0) 
    { 
    MessageBox.Show("Working"); 
    } 
    else 
    { 
    MessageBox.Show("Not Working"); 
    } 

人所以你可以使用一個定時器來檢查每個進程

7

reshefm有一個相當不錯的答案;然而,這並沒有說明這個過程從未開始的情況。

這是他發佈的內容的修改版本。

public static bool IsRunning(this Process process) 
    { 
     try {Process.GetProcessById(process.Id);} 
     catch (InvalidOperationException) { return false; } 
     catch (ArgumentException){return false;} 
     return true; 
    } 

我脫下ArgumentNullException,因爲它實際上是想要一個空引用異常,它就會被系統反正扔,我也佔了其中的過程是從來沒有開始,開始的形勢或接近( )方法被用來關閉該過程。

4

這應該是一個班輪:

public static class ProcessHelpers { 
    public static bool IsRunning (string name) => Process.GetProcessesByName(name).Length > 0; 
} 
0

儘管通過有關進程ID檢查現有流程的.Net框架支持的API,這些功能都非常慢。運行Process.GetProcesses()或Process.GetProcessById/Name()會花費大量的CPU週期。

通過ID檢查正在運行的進程的更快速的方法是使用本地API OpenProcess()。如果返回句柄爲0,則該過程不存在。如果句柄不是0,則進程正在運行。無法保證此方法在許可的情況下始終可以100%正常工作。

相關問題