【问题标题】:In C#, how to kill a process tree reliably [duplicate]在 C# 中,如何可靠地杀死进程树 [重复]
【发布时间】:2014-05-24 13:06:19
【问题描述】:

在 C# 中,我们使用以下代码来终止进程树。 有时有效,有时无效,可能与 Windows 7 和/或 64 位有关。

它查找给定进程的子进程的方法是调用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 { }
        }
    }

【问题讨论】:

  • Performing equivalent of "Kill Process Tree" in c++ on windows(显然你已经知道如何 P/Invoke)
  • 您的问题简化为“如何查找所有子进程”。杀死他们只是问题的一个微不足道的延伸。因此这是重复的。
  • @usr:感谢您的举报。我仍在尝试找出要使用的 using 语句。
  • @MikeDunlavey 不确定您的意思。听起来像是一项简单的研究任务,不管它是什么。如果做不到,请提出一个新问题。
  • 呃,如果我们将其作为副本关闭,我链接的问题是一个方式更好的选择。但我特别没有投票结束,因为它不是任何一个问题的完全重复。一方面,它使用不同的语言。即使翻译代码是微不足道的,它也不是重复的。 (迈克,我不知道你的意思是试图弄清楚要使用什么 using 声明。这是你说你绝望迷失的方式吗?如果你对 .NET 完全陌生,你可能想要提到这一点。我根据你的代表做了一些假设。;-))

标签: c# process


【解决方案1】:

使用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.
    }
 }

【讨论】:

  • 请原谅我的天真,但我尝试了using System.Management;,但这似乎并没有让我访问它。我一定是错过了什么。
  • 你添加了对System.Management.dll的引用吗?
  • 做到了。感谢您帮助我解决问题。
  • 您不想先杀死父进程以避免它重新启动进程吗?
猜你喜欢
  • 2020-07-26
  • 2012-06-08
  • 2011-08-19
  • 2020-09-22
  • 2013-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-27
相关资源
最近更新 更多