7

I'm looking for the best, or any way really to start a process from php in the background so I can kill it later in the script.

Right now, I'm using: shell_exec($Command); The problem with this is it waits for the program to close.

I want something that will have the same effect as nohup when I execute the shell command. This will allow me to run the process in the background, so that later in the script it can be closed. I need to close it because this script will run on a regular basis and the program can't be open when this runs.

I've thought of generating a .bat file to run the command in the background, but even then, how do I kill the process later?

The code I've seen for linux is:

$PID = shell_exec("nohup $Command > /dev/null & echo $!");
// Later on to kill it
exec("kill -KILL $PID");

EDIT: Turns out I don't need to kill the process

Mobiler
  • 255
  • 3
  • 10
William W
  • 1,776
  • 6
  • 21
  • 40

5 Answers5

11

shell_exec('start /B "C:\Path\to\program.exe"');

The /B parameter is key here.

I can't seem to find where I found this anymore. But this works for me.

Community
  • 1
  • 1
Jelmer
  • 2,663
  • 2
  • 27
  • 45
  • 2
    For sake of completeness, I leave the link to the docs about the start command here: https://technet.microsoft.com/en-us/library/cc770297(v=ws.11).aspx – zinky Nov 19 '17 at 12:55
5

Will this function from the PHP Manual help?

function runAsynchronously($path,$arguments) {
    $WshShell = new COM("WScript.Shell");
    $oShellLink = $WshShell->CreateShortcut("temp.lnk");
    $oShellLink->TargetPath = $path;
    $oShellLink->Arguments = $arguments;
    $oShellLink->WorkingDirectory = dirname($path);
    $oShellLink->WindowStyle = 1;
    $oShellLink->Save();
    $oExec = $WshShell->Run("temp.lnk", 7, false);
    unset($WshShell,$oShellLink,$oExec);
    unlink("temp.lnk");
}
Alix Axel
  • 151,645
  • 95
  • 393
  • 500
  • I ended up using (almost) this to launch a batch file and it works perfectly now. – William W Jan 16 '10 at 19:01
  • Sorry for digging out this old grave. I m using same code to execute external program i made in C#. The browser/php script or apache just hangs, if this c# application throws an exception. Is there any work around for this?? – WatsMyName Oct 30 '13 at 08:07
3

Tried to achieve the same on a Windows 2000 server with PHP 5.2.8.

None of the solutions worked for me. PHP kept waiting for the response.

Found the solution to be :

$cmd = "E:\PHP_folder_path\php.exe E:\some_folder_path\backgroundProcess.php";
pclose(popen("start /B ". $cmd, "a"));  // mode = "a" since I had some logs to edit
Rohit
  • 439
  • 8
  • 18
1

From the php manual for exec:

If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.

ie pipe the output into a file and php won't wait for it:

exec('myprog > output.txt');

From memory, I believe there is a control character that you can prepend (like you do with @) to the exec family of commands that also prevents execution from pausing - can't remember what it is though.

Edit Found it! On unix, programs executed with & prepended will run in the background. Sorry, doesn't help you much.

Adam Hopkinson
  • 28,281
  • 7
  • 65
  • 99
  • I ended up using the batch file and doing: system("cmd /c C:[path to file]"); That keeps the script going. Any ideas on how to kill the process? This actually opens up Adobe Reader, and I still need a way to close it before the script runs again. – William W Jan 14 '10 at 22:34
  • Nevermind, turns out I don't need to kill the process. I can leave it running. – William W Jan 14 '10 at 22:46
  • 2
    I'm currently trying this on a windows system and it is still waiting for the script to end in the browser window regardless of the fact it is outputting into a file. Any thoughts on this? – php_nub_qq Oct 19 '14 at 12:15
  • @WilliamW W if you will refresh this window a new instance will be created and this may be problematic for some of us – Pini Cheyni Mar 14 '16 at 14:27
1

On my Windows 10 and Windows Server 2012 machines, the only solution that worked reliably within pclose/popen was to invoke powershell's Start-Process command, as in:

pclose(popen('powershell.exe "Start-Process foo.bat -WindowStyle Hidden"','r'));

Or more verbosely if you want to supply arguments and redirect outputs:

pclose(popen('powershell.exe "Start-Process foo.bat 
             -ArgumentList \'bar\',\'bat\' 
             -WindowStyle Hidden
             -RedirectStandardOutput \'.\\console.out\' 
             -RedirectStandardError \'.\\console.err\'"','r'));
Mike Godin
  • 3,727
  • 3
  • 27
  • 29