Kill process tree programmatically in C#

robr picture robr · May 5, 2011 · Viewed 60.3k times · Source

I am starting Internet Explorer programmatically with code that looks like this:

ProcessStartInfo startInfo = new ProcessStartInfo("iexplore.exe");
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = "http://www.google.com";
Process ieProcess = Process.Start(startInfo);

This generates 2 processes visible in the Windows Task Manager. Then, I attempt to kill the process with:

ieProcess.Kill();

This results in one of the processes in Task Manager being shut down, and the other remains. I tried checking for any properties that would have children processes, but found none. How can I kill the other process also? More generally, how do you kill all the processes associated with a process that you start with Process.Start?

Answer

Contango picture Contango · May 1, 2012

This worked very nicely for me:

/// <summary>
/// Kill a process, and all of its children, grandchildren, etc.
/// </summary>
/// <param name="pid">Process ID.</param>
private static void KillProcessAndChildren(int pid)
{
    // Cannot close 'system idle process'.
    if (pid == 0)
    {
        return;
    }
    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.
    }
}

Update 2016-04-26

Tested on Visual Studio 2015 Update 2 on Win7 x64. Still works as well now as it did 3 years ago.

Update 2017-11-14

Added check for system idle process if (pid == 0)

Update 2018-03-02

Need to add a reference to the System.Management namespace, see comment from @MinimalTech below. If you have ReSharper installed, it will offer to do this for you automatically.

Update 2018-10-10

The most common use case for this is killing any child processes that our own C# process has started.

In this case, a better solution is to use Win32 calls within C# to make any spawned process a child process. This means that when the parent process exits, any child processes are automatically closed by Windows, which eliminates the need for the code above. Please let me know if you want me to post the code.