获取进程的PID由Process.start()启动

我正在使用此代码启动可执行文件:

Process proc = new Process(); proc.StartInfo.FileName = executablePath; proc.Start(); proc.WaitForInputIdle(); 

在这个调用proc.Id它给了我一些整数,这不是真正的进程ID。 在任务管理器中,此进程还有另一个ID,我也使用MS UI Automation访问此应用程序,该应用程序也返回与任务管理器中相同的ID。 所以我的问题是如何获得启动过程的真实进程ID?

UPDATE

我发现在Windows 7上它工作正常并返回正确的ID,但不是在Windows XP上。 可能是什么原因?

情景

该应用程序的场景如下。 我有一个正在运行的嵌入式HTTP服务器,它不是由我实现的( 这里是源代码)。 客户端连接到Web服务器并发送运行程序的请求。 在我的服务器的请求处理程序中,我只是使用Process.start()来启动所请求的应用程序。 作为Web服务器,程序为连接到它的每个客户端会话创建线程(我假设如此,因为我没有写它)。 这可以以某种方式帮助识别问题,因为它只存在于Windows XP X86 Service Pack 3上吗?

我是如何做到的一个例子:

  bool started = false; var p = new Process(); p.StartInfo.FileName = "notepad.exe"; started = p.Start(); try { var procId = p.Id; Console.WriteLine("ID: " + procId); } catch(InvalidOperationException) { started = false; } catch(Exception ex) { started = false; } 

否则,尝试使用这样的句柄:
使用处理程序
获得处理程序

 hWnd = (int) process.MainWindowHandle; int processId; GetWindowThreadProcessId(hWnd, out processId); [DllImport("user32")] static extern int GetWindowThreadProcessId(IntPtr hWnd, out int processId); 

边注:
如果获得进程数组并迭代它们并比较PID,会发生什么?

 Process[] p = Process.GetProcessesByName( "testprogram" ); foreach(var proc in p) Console.WriteLine("Found: "+proc.Id == myExpectedProcId); 

这个:

 using (Process process = Process.Start("notepad.exe")) { process.WaitForInputIdle(); Console.WriteLine(process.Id); } 

实际上对我有用:

http://pasteboard.s3.amazonaws.com/images/1350293463417532.png

任务管理器:

http://pasteboard.s3.amazonaws.com/images/1350293536498959.png

我的想法:

实际上你的进程启动另一个进程正在尝试获取某种启动器的ID。 (它可以顺便开始)。

下面还返回一个进程的PID

 Process[] p = Process.GetProcessesByName("YourProcessName"); 

现在,您可以使用p[i].Id;获取进程ID p[i].Id;

我只是想在这里猜测,因为如果没有看到真正的代码,很难理解真正发生的事情。 无论如何,你在一条评论中提到了Trhreads。 是否有可能在主线程中初始化了一个Process类型的变量proc,然后该流程在另一个Thread中启动?

如果是这种情况,可能会多次启动该进程,并且您只获得其中一个进程的PID。 我能够重现你的案例的唯一方法就是这样:

  private Process proc; private List pids = new List(); public void StartProc() { // this tries to simulate what you're doing. Starts the process, then // wait to be sure that the second process starts, then kill proc proc.Start(); pids.Add(proc.Id); Thread.Sleep(300); try { proc.Kill(); } catch {} } // the method returns the PID of the process public int Test() { proc = new Process(); proc.StartInfo.FileName = @"notepad.exe"; for (int i = 0; i < 2; i++) { Thread t = new Thread(StartProc); t.Start(); Thread.Sleep(200); } Thread.Sleep(500); return proc.Id; } 

执行Test时,您应该看到一个活动的记事本,并且该方法返回的PID与任务管理器显示的PID不同。 但是如果你看一下pids List,你会发现任务管理器PID是列表中的第一个元素,而方法返回的是第二个元素。

你有可能做过类似的事吗?