System.Diaganostics.Process.Id不是任务管理器中显示的相同进程ID。 为什么?

我正在使用C#的System.Diagnostic.Process对象。
它的一个属性是Id
此生成的IdWindows Task Manager显示的PID
为什么是这样?

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

我正在尝试通过PID找到一种可靠的方法来终止此进程和所有关联的进程,这是在Task Manager中显示的进程。
有没有更好的办法?

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

关键是你不想通过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; } } 

我无法重现这一点。 我刚刚运行以下代码:

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

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