9

我正在使用 C# 的System.Diagnostic.Process对象。
它的特性之一是Id。this 产生的 与 中
所示的不同。为什么是这样?IdPIDWindows Task Manager

你看,一旦这个过程开始。
它启动了另外两个非托管进程,我无法通过对象属性引用显式获取它们的 ID。
我必须搜索所有进程才能通过进程名称找到它们System.Diagnostics.Process.GetProcesses()

我试图找到一种可靠的方法来杀死这个进程和所有相关进程PID,显示在Task Manager.
有没有更好的办法?

我不能只杀死具有关联进程名称的所有进程,因为这可能会杀死那些与我的程序无关的进程的其他实例。

4

2 回答 2

14

关键是您不想通过 Id 杀死您的进程。事实上,这是一种竞争条件:您生成的进程可能会死亡,而另一个进程可能会使用相同的 Id 创建。然后当你去杀死它时,你最终会杀死新进程而不是已经死的旧进程。

杀死生成的进程最可靠的方法是将它们放在 Job 对象中,并在任务完成后终止 Job。

下面是一些实现 Job 类的简单代码:

class Job
{
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    public static extern IntPtr CreateJobObject(IntPtr lpJobAttributes, string lpName);

    [DllImport("kernel32.dll")]
    public static extern bool AssignProcessToJobObject(IntPtr hJob, IntPtr hProcess);

    [DllImport("kernel32.dll")]
    public static extern bool TerminateJobObject(IntPtr hJob, uint uExitCode);

    IntPtr job;

    public Process StartProc(string commandLine)
    {
        if (job == IntPtr.Zero)
            job = CreateJobObject(IntPtr.Zero, null);
        ProcessStartInfo si = new ProcessStartInfo(@"c:\windows\system32\cmd.exe");
        si.Arguments = "/c " + commandLine;
        si.CreateNoWindow = false;
        si.UseShellExecute = false;
        Process proc = Process.Start(si);
        AssignProcessToJobObject(job, proc.Handle);
        return proc;
    }

    public void TerminateProc()
    {
        // terminate the Job object, which kills all processes within it
        if (job != null)
            TerminateJobObject(job, 0);
        job = IntPtr.Zero;
    }
}
于 2010-02-23T08:27:13.340 回答
1

我无法重现这个。我刚刚运行了以下代码:

foreach (var proc in Process.GetProcesses()
                            .OrderBy(proc => proc.Id))
{
    Console.WriteLine("{0}: {1}", p.Id, p.ProcessName);
}

列出的所有进程都与任务管理器中的 PID 匹配。这是使用 Windows 7 - 您使用的是什么操作系统?如果您查看其他进程,它们是否与任务管理器中显示的 PID 匹配?

于 2010-02-23T08:24:30.890 回答