How to get PID from PHP function exec() in Windows?

11,711

Solution 1

You will have to install an extra extension, but found the solution located at Uniformserver's Wiki.

UPDATE

After some searching you might look into tasklist which coincidently, you may be able to use with the PHP exec command to get what you are after.

Solution 2

I'm using Pstools which allows you to create a process in the background and capture it's pid:

// use psexec to start in background, pipe stderr to stdout to capture pid
exec("psexec -d $command 2>&1", $output);
// capture pid on the 6th line
preg_match('/ID (\d+)/', $output[5], $matches);
$pid = $matches[1];

It's a little hacky, but it gets the job done

Solution 3

I landed here thanks to google and decided that this ten years old post needs more info based on How to invoke/start a Process in PHP and kill it using Process ID...

Imagine that you want to execute a command (this example uses ffmpeg to stream a file on a windows system to a rtmp server). You could command something like this:

ffmpeg -re -i D:\wicked_video.mkv -c:v libx264 -preset veryfast -b:v 200k -maxrate 400k -bufsize 6000k -pix_fmt yuv420p -g 50 -c:a aac -b:a 160k -ac 2 -ar 44100 -f flv rtmp://<IP_OF_RMTP_SERVER>/superawesomestreamkey > d:\demo.txt 2> d:\demoerr.txt

The first part is explained here and the last part of that command outputs to files with that name for logging purposes:

> d:\demo.txt 2> d:\demoerr.txt

So lets assume that that command works. You tested it. To run that command with php you can execute it with exec but it will take time (another subject, check set_time_limit), its a video handled by ffmpeg via php. Not the way to go but it is happening in this case.

You can run the command in background but what is the pid of that Process? We want to kill it for some reason and psexec gives only the 'process ID" runned by a user. And there is only one user in this case. We want multiple processes on the same user.

Here is a example to get the pid of a runned process in php:

// the command could be anything:
// $cmd = 'whoami';

// This is a f* one, The point is: exec is nasty.
// $cmd = 'shutdown -r -t 0'; // 

// but this is the ffmpeg example that outputs seperate files for sake
$cmd = 'ffmpeg -re -i D:\wicked_video.mkv -c:v libx264 -preset veryfast -b:v 200k -maxrate 400k -bufsize 6000k -pix_fmt yuv420p -g 50 -c:a aac -b:a 160k -ac 2 -ar 44100 -f flv rtmp://10.237.1.8/show/streamkey1 > d:\demo.txt 2> d:\demoerr.txt';

// we assume the os is windows, pipe read and write
$descriptorspec = [  
    0 => ["pipe", "r"],  
    1 => ["pipe", "w"],  
];

// start task in background, when its a recource, you can get Parent process id
if ( $prog = is_resource( proc_open("start /b " . $cmd, $descriptorspec, $pipes ) ) )  
{  
    // Get Parent process Id  
    $ppid = proc_get_status($prog);  

    // this is the 'child' pid
    $pid = $ppid['pid'];

    // use wmic to get the PID
    $output = array_filter( explode(" ", shell_exec("wmic process get parentprocessid,processid | find \"$pid\"" ) ) );  
    array_pop($output);   
    
    // if pid exitst this will not be empty
    $pid = end($output);  

    // outputs the PID of the process 
    echo $pid;  
}  

The code above should echo the pid of the 'inBackground' runned process.

Note that you need to save the pid to kill it later if it is still running.

Now you can do this to kill the process: (imagine the pid is 1234)

//'F' to Force kill a process  
exec("taskkill /pid 1234 /F"); 

Here is my first post ever here on stackoverflow, I hope this will help someone. Have a awesome and not lonely christmas ♪♪

Share:
11,711
jarkam
Author by

jarkam

Updated on June 04, 2022

Comments

  • jarkam
    jarkam almost 2 years

    I have always used:

    $pid = exec("/usr/local/bin/php file.php $args > /dev/null & echo \$!");
    

    But I am using an XP virtual machine to develop a web app and I have no idea how to get the pid in windows.

    I tried this on a cmd:

    C:\\wamp\\bin\\php\\php5.2.9-2\\php.exe "file.php args" > NUL & echo $!
    

    And it gets the file executed, but the output is "$!"

    How can I get the pid into the var $pid? (using php)

  • jarkam
    jarkam over 13 years
    Thanks, anyway I think I will just setup a server on a linux virtual box, I just dont like having a webserver on my main OS and the only one I had was on win.
  • Jim
    Jim over 13 years
    Updated, found a program that is built into xp called tasklist which may do what you want.
  • relipse
    relipse almost 10 years
    That worked for me, however there was an extra console window which popped up for some reason
  • Slawa
    Slawa over 3 years
    It's a hell of the workaround, but it works. Thank you. Checking is_resource should be separate from assigning $prog, though.
  • Carlo Hendrikx
    Carlo Hendrikx over 3 years
    Yeah, reading trough the comments hehe. I noticed that later. Now im doing it with NodeJS. Glad this helped you!