I am having trouble using Process.Kill()
. I think I must be misunderstanding how it works. This is my test function. I start a long-running process (ping -t
) and then kill it five seconds later.
I can see the ping process show up, but the process is still there after my program finishes. I have to kill it manually.
Console.WriteLine("Total number of ping processes is {0}", Process.GetProcessesByName("ping").Length); ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe"); Process process = new Process(); startInfo.CreateNoWindow = true; startInfo.UseShellExecute = false; startInfo.Arguments = "/c ping -t 8.8.8.8"; Console.WriteLine("Staring ping process"); process.StartInfo = startInfo; process.Start(); Thread.Sleep(5000); Console.WriteLine("Total number of ping processes is {0}", Process.GetProcessesByName("ping").Length); Thread.Sleep(5000); Console.WriteLine("Killing ping process"); process.Kill(); Thread.Sleep(5000); Console.WriteLine("Total number of ping processes is {0}", Process.GetProcessesByName("ping").Length);
What am I doing wrong here?
Description. The kill command sends a signal (by default, the SIGTERM signal) to a running process. This default action normally stops processes.
When you kill process, everything that process owns, including threads is also killed. The Terminated property is irrelevant. The system just kills everything.
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.) } } }
This is a patch for the @SulNR answer since its answer leak child processes of child processes.
private static void KillProcessAndChildrens(int pid) { ManagementObjectSearcher processSearcher = new ManagementObjectSearcher ("Select * From Win32_Process Where ParentProcessID=" + pid); ManagementObjectCollection processCollection = processSearcher.Get(); // We must kill child processes first! if (processCollection != null) { foreach (ManagementObject mo in processCollection) { KillProcessAndChildrens(Convert.ToInt32(mo["ProcessID"])); //kill child processes(also kills childrens of childrens etc.) } } // Then kill parents. try { Process proc = Process.GetProcessById(pid); if (!proc.HasExited) proc.Kill(); } catch (ArgumentException) { // Process already exited. } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With