Process.Kill()似乎没有杀死进程

Kri*_*per 16 .net c# kill process

我无法使用Process.Kill().我想我一定是在误解它是如何运作的.这是我的测试功能.我开始一个长时间运行的进程(ping -t),然后在五秒后终止它.

我可以看到ping进程显示,但程序结束后进程仍然存在.我必须手动杀死它.

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);
Run Code Online (Sandbox Code Playgroud)

我在这做错了什么?

Sul*_*lNR 20

您启动了cmd.exe,然后cmd.exe启动子进程ping.exe.要杀死ping.exe,您可以终止所有进程层次结构.例如,使用WMI(添加System.Management引用):

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.)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果子进程产生自己的进程怎么办?我们需要一些方法来递归地杀死整棵树,不是吗? (2认同)
  • 请注意,应该更新此答案以反转对 `KillProcessAndChildrens` 的递归调用和对 `proc.Kill()` 的调用,因为如果你在孩子之前杀死父母,你只会失去孩子产生的进程,你会泄漏它们。看我的新提议。 (2认同)

Jul*_*lio 6

这是@SulNR答案的补丁,因为它的答案会泄漏子进程的子进程。

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.
    }
}
Run Code Online (Sandbox Code Playgroud)