In C#, how to kill a process tree reliably

c#, process

Solution

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

Problem

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 { } } } ```

Original source

Related problems