在C#中,如何可靠地杀死进程树 [英] In C#, how to kill a process tree reliably

查看:110
本文介绍了在C#中,如何可靠地杀死进程树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中,我们使用以下代码杀死进程树.有时它可以工作,有时却不起作用,这可能与Windows 7和/或64位有关.

In C#, we use the following code to kill a process tree. Sometimes it works, and sometimes it doesn't, possibly having to do with Windows 7 and/or 64-bit.

查找给定进程的子进程的方式是,调用 GetProcesses 来获取系统中的所有进程,然后调用 NtQueryInformationProcess 来找出其父级的每个进程是给定的过程.它以递归的方式进行操作,以走树.

The way it finds children of the given process is by calling GetProcesses to get all the processes in the system, and then calling NtQueryInformationProcess to find out every process whose parent is the given process. It does this recursively, to walk the tree.

在线文档显示不应使用 NtQueryInformationProcess .相反,有一个叫做 EnumProcesses 的东西,但是我找不到C#中的任何示例,只能找到其他语言.

The on-line doc says NtQueryInformationProcess should not be used. Instead there is something called EnumProcesses, but I can't find any examples in C#, only other languages.

杀死C#中的进程树的可靠方法是什么?

What's a reliable way to kill a tree of processes in 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 { }
        }
    }

推荐答案

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

这篇关于在C#中,如何可靠地杀死进程树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆