Получение PID процесса, начатого Process.start() - программирование
Подтвердить что ты не робот

Получение PID процесса, начатого Process.start()

Я запускаю исполняемый файл, используя этот код:

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

после этого вызова proc.Id он дает мне целое число, которое не является реальным идентификатором процесса. В диспетчере задач есть еще один идентификатор для этого процесса, а также я использую MS UI Automation для доступа к этому приложению, которое также возвращает тот же идентификатор, что и в диспетчере задач. Итак, мой вопрос: как я могу получить реальный идентификатор процесса запущенного процесса?

UPDATE

Я узнал, что в Windows 7 он отлично работает и возвращает мне правильный ID, но не в Windows XP. В чем может быть причина?

СЦЕНАРИЙ

Сценарий приложения следующий. У меня есть встроенный HTTP-сервер, который реализован не мной (здесь является источником). Клиент подключается к веб-серверу и отправляет запрос на запуск программы. В обработчике запросов моего сервера я просто использую Process.start() для запуска запрошенного приложения. В качестве веб-сервера программа создает потоки для каждого подключенного к ней клиентского сеанса (я предполагаю, что так, как я ее не писал). Может ли это как-то помочь идентифицировать проблему, поскольку она существует только в Windows XP X86 с пакетом обновления 3 (SP3)?

4b9b3361

Ответ 1

Пример того, как я это сделал:

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

Ответ 2

Это:

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

Мои мысли:

На самом деле ваш процесс запускает другой процесс, и вы пытаетесь получить идентификатор какой-то пусковой установки. (Он может начать, кстати, сам).

Ответ 3

Ниже также возвращается PID процесса

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

Теперь вы можете получить идентификатор процесса, используя p.Id;

Ответ 4

Я просто пытаюсь угадать здесь, так как трудно понять, что на самом деле происходит, не видя реального кода. В любом случае, вы упомянули Trhreads в одном из своих комментариев. Возможно ли, что у вас есть одна переменная proc типа Process, которая инициализируется в основном потоке, а затем процесс запускается в другом потоке?

Если это так, возможно, процесс запускается несколько раз, и вы получаете 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, возвращаемый методом, отличается тем, что показан диспетчером задач. Но если вы посмотрите на список pids, вы увидите, что PID диспетчера задач является первым элементом в списке, а тот, который возвращается методом, является вторым.

Возможно ли, что вы сделали что-то подобное?