Hans: exec als Hintergrundprozess unter Windows

Hallo,

ich habe folgendes Zielsystem und daran läßt sich (leider) auch nix ändern: Betriebssystem: Windows 2008 und 2012 Server Webserver IIS PHP Version 5.4.x als FastCGI

Die Aufgabe: es soll via PHP Script ein Kommandozeilen Tool angesteuert werden, welches über den Client diverse Parameter übergeben bekommt und dann umfangreiche Daten aus einer DB in verschiedene Formate exportiert. Diese Daten sollen dann gezipt und zum Download bereitgestellt werden. Da der Export zum Teil recht lange dauert soll dies in einem eigenen Prozess im Hintergrund laufen, und eine Benachrichtigung via mail abgesetzt werden, wenn die Daten zum Download bereitstehen.

Mit folgender Funktion bekomme ich solch einen Prozess schon mal ausgeführt und die Daten:

function execInBackground($cmd) {
    if (substr(php_uname(), 0, 7) == "Windows"){
        pclose(popen("start /B ". $cmd, "r")); 
    }
    else {
        exec($cmd . " > /dev/null &");  
    }
}


$cmd1 = 'meinprogram.exe -f "param1" -c "param2" "zielformat" "zielfile"';
execInBackground($cmd1);

Wie kann ich nun ermitteln, ob der Prozess abgeschlossen ist um die weiteren Schritte auszuführen (Mail absetzten etc.)? Oder bin ich mit so einem Vorgehen vollkommen auf dem Holzweg? Danke + Gruß Hans

  1. Hallo und guten Nachmittag,

    Wie kann ich nun ermitteln, ob der Prozess abgeschlossen ist um die weiteren Schritte auszuführen (Mail absetzten etc.)? Oder bin ich mit so einem Vorgehen vollkommen auf dem Holzweg?

    Nein, nicht ganz. Ich hatte eben nur erst falsch gelesen. Du willst kein PHP-Script im Hintergrund ausführen, sondern ein Executable.

    Wenn Du das überwachen willst, dann solltest Du nicht das Executable selbst in den Hintergund stellen, denn auf dessen Funktionsweise hast Du vermutlich keinen Einfluss mehr? Stelle ein Shellscript in den Hintergrund, die das Executable startet und dann dessen Exit-Code auswertet und dann darauf reagiert.

    Ich bastele immer PHP-Endlos-Scripte, die mit einer Instanz des Interpreters in den Hintergrund gestellt werden und die dann beim Exit noch eine Shutdown-Funktion auslösen. Die bekommen immer ein PID-File zur Kontrolle. Nur solange das File vorhanden ist, läuft der Prozess. Der Prozess selber benennt dann am Ende das PID-File um, sodass man sehen kann, wann er ordentlich zuende gelaufen ist.

    So ähnlich könntest Du das auch machen.

    Grüße
    TS

  2. Hallo und guten Abend nochmal,

    Mit folgender Funktion bekomme ich solch einen Prozess schon mal ausgeführt und die Daten:

    function execInBackground($cmd) {
        if (substr(php_uname(), 0, 7) == "Windows"){
            pclose(popen("start /B ". $cmd, "r")); 
        }
        else {
            exec($cmd . " > /dev/null &");  
        }
    }
    
    
    $cmd1 = 'meinprogram.exe -f "param1" -c "param2" "zielformat" "zielfile"';
    execInBackground($cmd1);
    
    

    Da hast Du mir eine schöne Abendaufgabe hinterlassen :-)

    Nur mal so vorab: das obige geht auch mit exec():

    
    function execInBackground($cmd) 
    {
        if (substr(php_uname(), 0, 7) == "Windows")
        {
            $result = exec("start /b ". $cmd, $_output, $errors); 
        }
        else 
        {
            $pid = exec($cmd . " > /dev/null & echo $!" );  
        }
    }
    

    Was willst Du mit dem Prozesszeiger, wenn Du ihn sofort wieder wegwirfst? Da bleibe ich mit meinem Verständnis für dein Beispiel stecken.

    Allerdings könnte das ein Lösungsweg sein, wenn man ihn aufhebt. Solange der Prozess läuft, müsste der Zeiger gültig bleiben. Kann man einen Prozesszeiger extern speichern, so wie eine ProzessID? Sonst müsstest Du Dir einen Daemon basteln, der die Prozesse startet und überwacht.

    Grüße
    TS