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
Export to Excel from a List with Epplus
C# Short/Long/Int Literal Format
When Is a Custom Attribute's Constructor Run
Collection<T> Versus List<T> What Should You Use on Your Interfaces
Understanding Async/Await in C#
How Big Is an Object Reference in .Net
How to Compare (Directory) Paths in C#
Get All Controls of a Specific Type
Why Does "Int[] Is Uint[] == True" in C#
How to Invoke an Extension Method Using Reflection
Smoothly Connecting Circle Centers
Prevent Using Dispatcher.Invoke in Wpf Code
Mail Sending with Network Credential as True in Windows Form Not Working