2011-08-25 45 views
6

我有一個.NET類庫,它啓動了一個繼續運行的輔助進程,直到我處理完這個對象。查找我自己.NET進程的所有子進程/查明給定進程是否屬於我自己的子進程?

由於程序滯留在內存中的一些事件,我決定添加一個集成測試以確保如果我讓對象失效到GC/Finalization,那麼這個過程就會停止。

但是,由於該過程是Mercurial命令行客戶端,而且我的構建服務器已經將Mercurial作爲其自身操作的一部分運行,所以我設想Mercurial在測試開始時已經運行或者已啓動,並且在測試結束時仍然在運行,與構建服務器有關,而不是我的測試。

因此,我想確保我找到(或不是)我開始的Mercurial客戶端,而不僅僅是當前正在運行的任何客戶端。

所以,問題是這樣的:

  • 我怎樣才能找出如果水銀客戶端,我看着被我的過程開始了嗎?

通過「看」,我在尋找使用Process.GetProcesses方法,但這不是一個要求。

如果不同的問題更好,「如何找到所有我自己的進程的子進程」,即。更容易回答,那也是綽綽有餘。

我發現此頁面:How I can know the parent process ID of a process?,但似乎我必須給它的進程名稱。如果我只是給它「hg」,那麼對於我所尋找的情況,這個問題不是太模棱兩可嗎?

回答

16

碰巧我周圍有一些C#/ WMI代碼,它會遞歸地殺死指定進程id產生的所有進程。殺戮顯然不是你想要的,但子進程的發現似乎是你感興趣,我希望這是有幫助的。

private static void KillAllProcessesSpawnedBy(UInt32 parentProcessId) 
    { 
     logger.Debug("Finding processes spawned by process with Id [" + parentProcessId + "]"); 

     // NOTE: Process Ids are reused! 
     ManagementObjectSearcher searcher = new ManagementObjectSearcher(
      "SELECT * " + 
      "FROM Win32_Process " + 
      "WHERE ParentProcessId=" + parentProcessId); 
     ManagementObjectCollection collection = searcher.Get(); 
     if (collection.Count > 0) 
     { 
      logger.Debug("Killing [" + collection.Count + "] processes spawned by process with Id [" + parentProcessId + "]"); 
      foreach (var item in collection) 
      { 
       UInt32 childProcessId = (UInt32)item["ProcessId"]; 
       if ((int)childProcessId != Process.GetCurrentProcess().Id) 
       { 
        KillAllProcessesSpawnedBy(childProcessId); 

        Process childProcess = Process.GetProcessById((int)childProcessId); 
        logger.Debug("Killing child process [" + childProcess.ProcessName + "] with Id [" + childProcessId + "]"); 
        childProcess.Kill(); 
       } 
      } 
     } 
    } 
+1

這對我來說很好,儘管我使用了ManagementObject而沒有搜索器的簡單方法。我一直在努力處理我的子流程一段時間,謝謝! – Darkhydro

+0

拯救生命!!!!!! – mstrewe

0

Altough的answer of mtijn可能是你可以GER最接近時,真正的答案是:你不能。

Windows不維護一個真正的進程樹,其中進程在中間級別上的進程死亡時重新構造。但是,Windows確實記得父進程ID。

有問題的情況下是這樣的:

原始過程結構:

YourApp.exe 
- SubApp.exe 
    - Second.exe 

如果現在SubApp.exe終止,Second.exe的父進程ID將不被更新。新結果是

YourApp.exe 
Second.exe 

您可以使用SysInternals Process Explorer來驗證這一點。它能夠將過程顯示爲一棵樹。啓動CMD,然後鍵入start cmd。進入新窗口,再次輸入start cmd。你會打開3個窗口。現在終止中間的一個。

相關問題