在 C# 中,如何可靠地杀死进程树 [重复]

Posted

技术标签:

【中文标题】在 C# 中,如何可靠地杀死进程树 [重复]【英文标题】:In C#, how to kill a process tree reliably [duplicate] 【发布时间】: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 完全陌生,你可能想要提到这一点。我根据你的代表做了一些假设。;-)) 【参考方案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的引用吗? 做到了。感谢您帮助我解决问题。 您不想先杀死父进程以避免它重新启动进程吗?

以上是关于在 C# 中,如何可靠地杀死进程树 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在 USR1 信号后可靠地杀死睡眠进程

如何使用 C 在 Linux 上以编程方式杀死进程树

杀死正在运行的程序的方法以及如何捕获它们?

如何区分具有相同名称的多个进程并杀死所有在 C# 中以我的 USERNAME 运行的进程?

无法弄清楚如何在 Python 3.5 中杀死子进程 [重复]

从python中杀死一个子进程,包括它的子进程[重复]