5

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.

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.

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.

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 { }
        }
    }
Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
  • 1
    [Performing equivalent of "Kill Process Tree" in c++ on windows](http://stackoverflow.com/q/604522) (clearly you already know how to P/Invoke) – Cody Gray - on strike May 24 '14 at 13:13
  • Your question reduces to "How to find all child processes". Killing them is a trivial extension of the problem. This is therefore a duplicate. – usr May 24 '14 at 13:22
  • @usr: Thanks for flagging that. I'm still trying to figure out what `using` statement to use. – Mike Dunlavey May 24 '14 at 13:39
  • @MikeDunlavey not sure what you mean. Sounds like a simple research task, whatever it is. If you can't do it, ask a new question. – usr May 24 '14 at 13:44
  • Uhh, the question I linked is a *way* better choice if we're closing this as a duplicate. But I specifically didn't vote to close, because it isn't an exact duplicate of either question. For one thing, it uses a different language. Even if translating the code is trivial, it's not a duplicate. (Mike, I don't know what you mean either by trying to figure out what `using` statement to use. Is that your way of saying you're hopelessly lost? If you're completely new to .NET, you might want to mention that. I made some assumptions looking at your rep. ;-)) – Cody Gray - on strike May 24 '14 at 13:51
  • @Cody: Rep is more a matter of time-on-site and general busyness. I'm still pretty new to .Net. – Mike Dunlavey May 24 '14 at 14:12

1 Answers1

9

Use ManagmentObjectSearcher and a little recursion:

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.
    }
 }
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321