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

发布于 2024-07-27 15:24:51 字数 629 浏览 9 评论 0 原文

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

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

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

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

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

  • 我的应用程序的子进程“A”(我认为是InstallAnywhere EXE)生成了真正的处理应用程序“B”(一个java.exe),它依次生成更多子项“C1”..“Cn”(其中大部分也是用 Java 编写的)。
  • 我的应用程序可能会在同一台计算机上运行多个副本(因此,其子级的多组)。
  • 子进程不在我的控制范围内,因此将来可能会出现一些“D”进程。
  • 我的应用程序必须在 32 位和 64 位版本的 MSWindows 上运行。

从好的方面来说,不存在数据丢失的问题,只要进程相当快地结束,“干净”的关闭并不重要。

Question: How can I determine all processes in the child's Process Tree to kill them?

I have an application, written in C# that will:

  1. Get a set of data from the server,
  2. Spawn a 3rd party utility to process the data, then
  3. Return the results to the server.

This is working fine. But since a run consumes a lot of CPU and may take as long as an hour, I want to add the ability to have my app terminate its child processes.

Some issues that make the simple solutions I've found elsewhere are:

  • My app's child process "A" (InstallAnywhere EXE I think) spawns the real processing app "B" (a java.exe), which in turns spawns more children "C1".."Cn" (most of which are also written in Java).
  • There will likely be multiple copies of my application (and hence, multiple sets of its children) running on the same machine.
  • The child process is not in my control so there might be some "D" processes in the future.
  • My application must run on 32-bit and 64-bit versions of MSWindows.

On the plus side there is no issue of data loss, a "clean" shutdown doesn't matter as long as the processes end fairly quickly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

伴我心暖 2024-08-03 15:24:51

我猜你可以用 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;
 }

I guess you can kill your grandchildren with this code from the MSDN forums.

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;
 }
人海汹涌 2024-08-03 15:24:51

根据本网站概述的解决方案,以下是一种紧凑的方法:

    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();
    }

Based on the solution outlined on this site, here is a compact way of doing it:

    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();
    }
无需解释 2024-08-03 15:24:51

以下代码适用于我:

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

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

The following code works for me:

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

It works for the scenario I have. I'd be interested to hear if that works for others as well.

-小熊_ 2024-08-03 15:24:51

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

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

I tested Jake Pearson's solution and for me this does not always work. I wanted to kill other process (with known pid) tree. The other process was using iexplore.exe running separately for each instance (IE 8 - more than one process). It works fine, but when used with WinAPI to hide IE window it stopped working.

I found solution on microsoft.public.dotnet.framework group, and it works fine now. Although Jake's answer can be useful in most cases, I think.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文