我正在使用此代码启动可执行文件:
Process proc = new Process();
proc.StartInfo.FileName = executablePath;
proc.Start();
proc.WaitForInputIdle();
在调用proc.Id
之后,它给了我一些整数,这不是真正的进程ID。在任务管理器中,此进程还有另一个ID,我也使用MS UI Automation来访问此应用程序,该应用程序也返回与任务管理器中相同的ID。所以我的问题是如何获得启动过程的真实进程ID?
更新
我发现在Windows 7上它工作正常并返回正确的ID,但不是在Windows XP上。可能是什么原因?
SCENARIO
该应用程序的场景如下。我有一个正在运行的嵌入式HTTP服务器,它不由我实现,(here是源)。客户端连接到Web服务器并发送运行程序的请求。在我的服务器的请求处理程序中,我只是使用Process.start()
来启动所请求的应用程序。作为Web服务器,程序为连接到它的每个客户端会话创建线程(我假设如此,因为我没有写它)。这有助于识别问题,因为它只存在于Windows XP X86 Service Pack 3上吗?
答案 0 :(得分:21)
我是如何做到的一个例子:
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;
}
否则,尝试使用这样的句柄:
Using handlers
Getting handler
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);
答案 1 :(得分:6)
此:
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。 (它可以顺便开始)。
答案 2 :(得分:2)
下面还返回进程的PID
Process[] p = Process.GetProcessesByName("YourProcessName");
现在,您可以使用p[i].Id;
答案 3 :(得分:0)
我只是想在这里猜测,因为如果没有看到真正的代码,很难理解真正发生的事情。无论如何,你在一条评论中提到了Trhreads。是否有可能在主线程中初始化了一个Process类型的变量proc,然后该流程在另一个Thread中启动?
如果是这种情况,可能会多次启动该进程,并且您只获得其中一个进程的PID。我能够重现你的案例的唯一方法是:
private Process proc;
private List<int> pids = new List<int>();
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是列表中的第一个元素,而方法返回的是第二个元素。
你有可能做过类似的事吗?