2014-05-24 29 views
4

在C#中,我們使用以下代碼來終止進程樹。 有時它有效,有時它不會,可能與Windows 7和/或64位有關。在C#中,如何可靠地終止進程樹

找到給定進程的子進程的方式是調用GetProcesses以獲取系統中的所有進程,然後調用NtQueryInformationProcess來查找其父進程是給定進程的每個進程。 它遞歸地執行此操作,以走樹。

在線文檔說不應使用NtQueryInformationProcess。 取而代之的是EnumProcesses,但我在C#中找不到任何示例,只有其他語言。

什麼是殺死C#中進程樹的可靠方法?

public static void TerminateProcessTree(Process process) 
    { 
     IntPtr processHandle = process.Handle; 
     uint processId = (uint)process.Id; 

     // Retrieve all processes on the system 
     Process[] processes = Process.GetProcesses(); 
     foreach (Process proc in processes) 
     { 
      // Get some basic information about the process 
      PROCESS_BASIC_INFORMATION procInfo = new PROCESS_BASIC_INFORMATION(); 
      try 
      { 
       uint bytesWritten; 
       Win32Api.NtQueryInformationProcess(proc.Handle, 0, ref procInfo, 
        (uint)Marshal.SizeOf(procInfo), out bytesWritten); // == 0 is OK 

       // Is it a child process of the process we're trying to terminate? 
       if (procInfo.InheritedFromUniqueProcessId == processId) 
       { 
        // Terminate the child process (and its child processes) 
        // by calling this method recursively 
        TerminateProcessTree(proc); 
       } 
      } 
      catch (Exception /* ex */) 
      { 
       // Ignore, most likely 'Access Denied' 
      } 
     } 

     // Finally, terminate the process itself: 
     if (!process.HasExited) 
     { 
      try 
      { 
       process.Kill(); 
      } 
      catch { } 
     } 
    } 
+1

(http://stackoverflow.com/q/604522)在C++中的窗口上執行的 「殺死進程樹」 等效(清楚你已經知道如何P/Invoke) –

+0

您的問題簡化爲「如何查找所有子進程」。殺死它們是問題的微不足道的延伸。因此這是重複的。 – usr

+0

@usr:感謝您舉報該問題。我仍然試圖找出使用'using'語句的用法。 –

回答

7

使用ManagmentObjectSearcher和少許遞歸:

private static void KillProcessAndChildren(int pid) 
{ 
    ManagementObjectSearcher searcher = new ManagementObjectSearcher 
     ("Select * From Win32_Process Where ParentProcessID=" + pid); 
    ManagementObjectCollection moc = searcher.Get(); 
    foreach (ManagementObject mo in moc) 
    { 
     KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"])); 
    } 
    try 
    { 
     Process proc = Process.GetProcessById(pid); 
     proc.Kill(); 
    } 
    catch (ArgumentException) 
    { 
     // Process already exited. 
    } 
} 
+0

原諒我的天真',但我試過'使用System.Management;',似乎並沒有給我訪問它。我肯定錯過了什麼。 –

+1

您是否添加了對「System.Management.dll」的引用? –

+1

這樣做。感謝您幫助我解決問題。 –

相關問題