2010-12-10 27 views
1

J'écris un couple de scripts PHP pour exécuter un programme, capturer c'est STDOUT et capturer le code retour quand il se termine. Ces programmes pourraient revenir instantanément, ou finir dans 20 minutes, donc je dois surveiller quand ils finissent.Exécuter le programme en arrière-plan, ET capturer le code retour (php & windows)

Je n'arrive pas à démarrer un programme en arrière-plan et à capturer le code retour [dans un fichier journal externe]. Si j'utilise simplement exec, ou proc_open, mon script PHP bloquera, ce qui n'est pas bon quand le processus prend 20 minutes.

Même si je ne peux pas capturer le code de retour, j'ai besoin de savoir quand le processus est terminé. (Je peux mettre les codes d'erreur dans le STDOUT à la place)

je peux utiliser exec("start my.exe"); et attraper le STDOUT, mais je ne peux pas

le code de retour (et pas savoir quand il est fini) J'ai pensé de le faire via un fichier batch exec(start my.bat); et dans le fichier de commandes attraper le code de retour, mais ma ligne de commande a des options dynamiques, donc je ferais tout à fait quelque chose comme;
exec("start cmd \"echo hello\");

Edit: Mais je ne l'ai pas trouvé un moyen de rendre dynamiquement une liste-commande de lot sur la ligne de commande. Si quelqu'un connaît une approche, je serais très reconnaissant.
cmd /C "echo hello" est la solution à ce

N'a pas besoin d'être multiplateforme, strictement Windows (XP-7)

+0

Que voulez-vous faire avec le code de retour? L'afficher sur un site Web? –

+0

Oui, j'utilise le code de retour pour déterminer l'erreur et la prochaine étape. Mais cela sert aussi à me dire que le processus est terminé. –

Répondre

0

D'accord, c'est là où je suis arrivé jusqu'à présent. Je me suis dit que je n'ai pas besoin d'un fichier batch dynamique, je peux juste fournir des args (duh). Je peux appeler exec("start Batch.bat log.txt stdout.txt c:\my.exe a b c"); et surveiller les fichiers journaux avec certains ajax (comme je le fais maintenant)

REM first 2 params are log filenames 
set LogFilename=%1 
shift 
set StdOutFilename=%1 
shift 

REM Code to concatonate all following params from here 
REM http://stackoverflow.com/questions/761615/is-there-a-way-to-indicate-the-last-n-parameters-in-a-batch-file 
set params=%1 
:loop 
shift 
if [%1]==[] goto afterloop 
set params=%params% %1 
goto loop 
:afterloop 

REM command line is everything after the log-filename param 
set CommandLine=%params% 
@echo log: %LogFilename% 
@echo stdout: %StdOutFilename% 
@echo command: %CommandLine% 

if ["%LogFilename%"]==[]  exit 255; 
if ["%StdOutFilename%"]==[] exit 254; 
if ["%CommandLine%"]==[]  exit 253; 

REM execute command hidden(/B), wait for it to finish so we can get the return code (/WAIT) and output to stdlog 
@start /B /WAIT %CommandLine% >> %StdOutFilename% 

REM log return code "RET X" 
@echo RET %ERRORLEVEL% >> %LogFilename% 

Et le code PHP appelant;

$BatchCommandLine = "start /D $Cwd /B /WAIT execute.bat $LogName %StdLogName $Exe $Params"; 
$OutputLine = exec($BatchCommandLine, $Output, $ReturnCode); 
if ($ReturnCode != 0) 
echo "Batch file failed to execute"; 

* EDIT: * Oops, exec() ne se lance pas en arrière-plan, même avec démarrage. Encore, résolu mes autres problèmes ...

+0

Évidemment, cela devrait être ERRORLEVEL et non% ERRORLEVEL% http://blogs.msdn.com/b/oldnewthing/archive/2008/09/26/8965755.aspx –