Kill Process Tree Programmatically in C#

Kill process tree programmatically in C#

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.

In C#, how to kill a process tree reliably

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

Kill Process and each child processes opened by the parent process (Like 'TaskKill /F /T' command)

Some ideas:

  • Identify and Kill Child Process (WinAPI and WMI)
  • How To End Process Tree (WinAPI)
  • Kill process tree programatically in C# (StackOverflow - WMI)

The two approaches being used are ManagementObjectSearcher (WMI) and WinAPI.

Process.Kill() doesn't seem to kill the process

You started cmd.exe, then cmd.exe starts child process ping.exe. To kill ping.exe you can kill all process hierarchy. For example with WMI(add System.Management reference):

private static void KillProcessAndChildrens(int pid)
{
ManagementObjectSearcher processSearcher = new ManagementObjectSearcher
("Select * From Win32_Process Where ParentProcessID=" + pid);
ManagementObjectCollection processCollection = processSearcher.Get();

try
{
Process proc = Process.GetProcessById(pid);
if (!proc.HasExited) proc.Kill();
}
catch (ArgumentException)
{
// Process already exited.
}

if (processCollection != null)
{
foreach (ManagementObject mo in processCollection)
{
KillProcessAndChildrens(Convert.ToInt32(mo["ProcessID"])); //kill child processes(also kills childrens of childrens etc.)
}
}
}

Kill some processes by .exe file name

Quick Answer:

foreach (var process in Process.GetProcessesByName("whatever"))
{
process.Kill();
}

(leave off .exe from process name)



Related Topics



Leave a reply



Submit