Итак, в PHP на Windows: возможно ли запустить исполняемый файл в фоновом режиме И получить его PID ? Я пришел к выводу, что обе задачи можно выполнять по отдельности, но не вместе.
Фоновая обработка процесса
Чтобы создать фоновый процесс, запускаемый через SHELL, необходимо использовать команду 'start /B "bg" myprog.exe'
, а процесс SHELL должен быть закрыт сразу после.
Для этого многие люди используют pclose( popen( ... ) )
примерно так pclose( popen( 'start /B "bg" myprog.exe', 'r') );
, но, насколько мне известно, невозможно извлечь pid
при использовании popen.
Поскольку невозможно получить pid
с popen, мы должны обратиться к proc_open.
Получение PID
Используя proc_open
, мы можем получить pid exe, если и только если bypass_shell
имеет значение true.
Если для bypass_shell
установлено значение false (по умолчанию), Windows возвращает pid
ОБОЛОЧКИ. Для получения дополнительной информации см .: https://bugs.php.net/bug.php?id=41052
Объяснение проблемы
Команда start /B
завершается неудачно при передаче в proc_open при bypass_shell = true
, поскольку она пропускает SHELL и отправляет аргументы командной строки непосредственно в myprog.exe, который не знает, что с ними делать.
И наоборот, если bypass_shell = false
(по умолчанию) и proc_close используются для немедленного закрытия ОБОЛОЧКИ, myprog.exe запускается в фоновом режиме, как при использовании pclose( popen( ... ) )
НО неверный pid
вернулся (мы получаем pid
из снаряда).
Итак, возможно ли фоновое отображение + правильный поиск pid возможно?
Если нет, то какая следующая лучшая вещь? Мне нужно сделать это для PHP-скрипта, который будет развернут на общем хостинге, чтобы сторонние расширения не могли быть установлены. Лучшее, что я могу придумать, это сделать снимок tasklist
до и после запуска myprog.exe в фоновом режиме, а затем провести перекрестный анализ результатов. Обратите внимание, что myprog.exe может работать одновременно.
Если это помогает, хотя это не должно иметь никакого значения, myprog.exe на самом деле является ffmpeg (который устанавливается на большинстве общих веб-хостов).
Временное решение
// background the process
pclose( popen( 'start /B "bg" ffmpeg.exe', 'r') );
// get the pid using tasklist
exec( 'TASKLIST /NH /FO "CSV" /FI "imagename eq ffmpeg.exe" /FI "cputime eq 00:00:00"', $output );
$output = explode( '","', $output[0] );
$pid = $output[1];