Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kill process tree programmatically in C#

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?

like image 742
robr Avatar asked May 05 '11 17:05

robr


People also ask

How do you kill a process tree?

If you select the process at the top of the tree you want kill, then press F9 followed by Enter it will close the process and the entire process tree in one go. In the screen shot below this action would cause Chrome and all sub process to be closed.

What is kill PID command?

Description. The kill command sends a signal (by default, the SIGTERM signal) to a running process. This default action normally stops processes. If you want to stop a process, specify the process ID (PID) in the ProcessID variable.

What happens to child process when parent is killed Windows?

The idea is to create a "job object" for your main application, and register your child processes with the job object. If the main process dies, the OS will take care of terminating the child processes.


1 Answers

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.

like image 82
Contango Avatar answered Sep 21 '22 09:09

Contango