如何在WXP(和更新的MSWindows)上使用C#终止所有子进程

问题:如何确定子进程树中的所有进程以杀死它们?

我有一个用C#编写的应用程序,它将:

  1. 从服务器获取一组数据,
  2. 然后,生成第三方实用程序来处理数据
  3. 将结果返回给服务器。

这工作正常。 但是由于运行会占用大量 CPU并且可能需要长达一个小时,因此我想添加使我的应用程序终止其子进程的能力。

使我在其他地方找到的简单解决方案的一些问题是:

  • 我的应用程序的子进程“A”(我认为是InstallAnywhere EXE)产生真正的处理应用程序“B”(一个java.exe ),它反过来产生更多的孩子“C1”..“Cn”(其中大部分也是用使用Java)。
  • 我的应用程序可能有多个副本 (因此,它的多个子集)在同一台机器上运行。
  • 子进程不在我的控制范围内,因此将来可能会有一些“D”进程。
  • 我的应用程序必须在32位 64位版本的MSWindows上运行。

从好的方面来说,没有数据丢失的问题,只要流程以相当快的速度结束,“干净”关闭就无关紧要了。

我想你可以用MSDN论坛中的代码杀死你的孙子孙女。

public bool killProcess(int pid) { bool didIkillAnybody = false; try { Process[] procs = Process.GetProcesses(); for (int i = 0; i < procs.Length; i++) { didIkillAnybody = GetParentProcess(procsIdea.Id) == pid) && killProcess(procsIdea.Id); } try { Process myProc = Process.GetProcessById(pid); myProc.Kill(); return true; } catch { } } catch (Exception ex) { try { new Logger().Write("Exception caught at JobExecution.killProcess()", ex.Message, System.Diagnostics.EventLogEntryType.Warning, false); } catch { } } return didIkillAnybody; } private int GetParentProcess(int Id) { int parentPid = 0; using (ManagementObject mo = new ManagementObject("win32_process.handle='" + Id.ToString() + "'")) { mo.Get(); parentPid = Convert.ToInt32(mo["ParentProcessId"]); } return parentPid; } 

基于本网站概述的解决方案,这是一种紧凑的方式:

  static public void KillChildren(int parentPid) { foreach (var pid in from ManagementBaseObject m in new ManagementObjectSearcher("select ProcessId from Win32_Process where ParentProcessId=" + parentPid).Get() select Convert.ToInt32(m["ProcessId"])) KillChildren(pid); Process.GetProcessById(parentPid).Kill(); } 

以下代码适用于我:

 private void KillProcessAndChildren(int pid) { using (var searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid)) using (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 */ } } } 

它适用于我的场景。 我很想知道这是否适用于其他人。

我测试了Jake Pearson的解决方案,对我而言,这并不总是有效。 我想杀死其他进程(使用已知的pid)树。 另一个进程是使用iexplore.exe为每个实例单独运行(IE 8 – 多个进程)。 它工作正常,但与WinAPI一起使用时隐藏IE窗口它停止工作。

我在microsoft.public.dotnet.framework组上找到了解决方案 ,现在工作正常。 虽然杰克的答案在大多数情况下都很有用,但我认为。