Получение 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)?
Ответы
Ответ 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 диспетчера задач является первым элементом в списке, а тот, который возвращается методом, является вторым.
Возможно ли, что вы сделали что-то подобное?