C# 通过 Process.start() 获取进程的 PID

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12892268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 00:51:55  来源:igfitidea点击:

getting PID of process started by Process.start()

c#.net-4.0processpid

提问by haynar

I am starting an executable using this code:

我正在使用以下代码启动一个可执行文件:

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

after this calling proc.Idit gives me some integer, which is not real process ID. In the task manager there is another ID for this process and also I am using MS UI Automation to access this application, which also returns the same ID as in task manager. So my question is how can I get the real process ID of started process?

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

UPDATE

更新

I found out that on Windows 7 it works fine and returns me the right ID, but not on Windows XP. What can be the reason?

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

SCENARIO

设想

The scenario of the application is the following. I have a running embedded HTTP server, which is implemented not by me, (hereis the source). The client connects to the web server and sends a request to run a program. In the request handler of my server I am just using Process.start()to start the requested application. As a web server the program creates threads for every client session connected to it (I assume so, as I didn't wrote it). Can this somehow help to identify the problem as it exists only on Windows XP X86 Service Pack 3?

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

采纳答案by Marcus

An example of how I did it:

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

    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;
    }

Otherwise, try using handles like this:
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);

Side note:
What happens if you get the array of process and iterate over them and compare the PIDs?

旁注:
如果您获取进程数组并对其进行迭代并比较 PID,会发生什么?

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

回答by AgentFire

This:

这个:

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

Actually works for me:

实际上对我有用:

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

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

Task Manager:

任务管理器:

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

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

My thoughts:

我的想法:

Actually your processstarts another processand youare trying to get ID of some kind of launcher. (It can start itself by the way).

实际上,您的进程启动了另一个进程,并且正在尝试获取某种启动器的 ID。(顺便说一下,它可以自己启动)。

回答by New Developer

Below also returns the PID of a process

下面还返回进程的PID

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

Now you can get process Id by using p[i].Id;

现在您可以使用 p[i].Id;

回答by Francesco Baruchelli

I'm just trying to guess here, since it's difficult to understand what's really happening without seeing the real code. Anyway, you mentioned Trhreads in one of your comment. Is it possible that you have a single variable proc of type Process which is initialized in your main thread, and then the process is started in a different Thread?

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

If this is the case, maybe the process is started more than once, and you get the PID of just one of them. The only way I was able to reproduce your case is this one:

如果是这种情况,则该进程可能不止一次启动,而您只获得其中一个的 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;
     }

When you executes Test, you should see a single active Notepad, and the PID returned by the method is different by the one showed by the Task Manager. But if you take a look at the pids List, you should see that the Task Manager PID is the first element in the list, and the one returned by the method is the second one.

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

Is it possible that you have done something similar?

你有没有做过类似的事情?