4

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

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

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

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

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

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

从好的方面来说,没有数据丢失的问题,只要进程很快结束,“干净”的关闭就没有关系。

4

4 回答 4

2

我猜你可以用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;
 }
于 2009-07-16T17:03:40.127 回答
2

以下代码适用于我:

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 */ }
  }
}

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

于 2011-03-02T20:27:10.043 回答
2

基于此站点上概述的解决方案,这是一种紧凑的方法:

    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();
    }
于 2011-09-05T15:13:04.960 回答
1

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

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

于 2010-03-09T09:17:55.783 回答