passthru, exe, bat und error 1

nietaL

NGBler
Registriert
8 Sep. 2013
Beiträge
231
Ort
Exilgullianer
Hey Leute,

mein php Script führt folgenden Code problem los aus:
[src=php]passthru("cpbo.exe -y -p missions/".$operation_ordner.".Altis",$err);[/src]
im Anschluss (immernoch selbe Script-Datei) soll eine *.bat (im selben Verzeichnis) ausgeführt werden
[src=php]passthru("start.bat",$err); echo "Fehler: ".$err;[/src]
Ausgabe: Fehler 1

Inhalt der bat-Datei:
[src=C]@echo off
start "" "C:\inetpub\vhosts\.......\arma\arma3server.exe" -config=server.cfg -port=2302
[/src]


Swohl die cpbo.exe also auch die start.bat haben dieselben Rechte, werden vom selben Script gestartet, liegen am selben Ort. Und trotzdem kommt bei dr *.bat-Datei ein Fehler 1. Und soweit ich weiß, ist alles bisauf 0 schlecht :dozey:

Ich erwarte jetzt keine hellseherischen Leistungen von euch. Eher einen Tip, wie ich debuggen kann. Mit "1" kann ich irgendwie gar nichts anfangen :-(


*edit*

Um das Problem an der Wurzel zu packen habe ich die bat-Datei umgeschrieben in:
[src=C]
@echo off
start calc.exe
exit
[/src]

Direkt gestartet funktionierts einwandfrei. Über PHP leider nicht.
 
Zuletzt bearbeitet:
Ich denke, dass die passthru()-Funktion keine Batchdateien unterstützt, habe jetzt auch nichts anderweitiges gefunden.

Kannst du nicht einfach statt [src=php]passthru("start.bat",$err); echo "Fehler: ".$err;[/src] folgendes tun?

[src=php]passthru("C:\inetpub\vhosts\.......\arma\arma3server.exe -config=server.cfg -port=2302",$err); echo "Fehler: ".$err;[/src]

Vielleicht liegt deine Exe-Datei auch außerhalb des ?

Wird die Variable $operation_ordner mit userinput generiert? Falls ja, solltest du die noch vorher escapen. Eventuell brauchst du auch für die URL in dem passthru()-Call, dann kannst du den Pfad als Unix-URL angeben:
[src=php]passthru(realpath(/inetpub/vhosts/.../arma/arma3server.exe)." -config=server.cfg -port=2302",$err); echo "Fehler: ".$err;[/src]
 
  • Thread Starter Thread Starter
  • #3
Hallo, vielen Dank für die ersten Hinweise.

Also ich habe deine Alternativen ausprobiert, leider beide mit selbem Effekt. "Fehler: 1"

safe_mode = off
safe_mode_exec_dir = no value

Vielleicht hilft der Hinweis, dass das erste Programm cpbo.exe zwar korrekt ausgeführt wird, aber trotzdem ebenfalls den Fehlercode 1 zurückgibt. Es handelt sich dabei um ein Consolenprogramm.

Der server an sich ist zwar auch nur eine Art Console, hat aber vorher einen kleinen Startbildschirm mit Ladebalken - ich weiß nicht, ab wann ein Programm als eines mit GUI zählt und ob das relevant ist.



Angenommen, man bekäme eine Batch-Datei zum laufen: Kann man da hinein dann alles schreiben? Oder prüft der Server vor Ausführung der Batch auch noch einmal deren Inhalt? Es erscheint mir einfacher eine Batch-Datei über PHP zu starten als eine Exe.
 
Ich denke, dass die passthru()-Funktion keine Batchdateien unterstützt, habe jetzt auch nichts anderweitiges gefunden.
Das ist in der Tat das Problem, denn Batch-Dateien sind nicht ausführbar (anders als z.B. Skripte unter unixoiden Systemen mit Shebang-Zeile und +x-Flag). Sie werden unter Windows bloss standardmässig unter dem Kommandozeileninterpreter (cmd.exe) ausgeführt, genau wie z.B. ein Öffnen/ShellExecute einer Datei mit Endung `docx` bei installiertem Microsoft Office dazu führt, dass dieses gestartet und das Dokument darin geladen wird. Denselben Effekt kannst du mit dem Kommando
Code:
Expand Collapse Copy
cmd.exe /r "C:\Path\to\batch.bat"
erreichen (unter der Voraussetzung dass sich cmd.exe im Suchpfad befindet).


Angenommen, man bekäme eine Batch-Datei zum laufen: Kann man da hinein dann alles schreiben? Oder prüft der Server vor Ausführung der Batch auch noch einmal deren Inhalt? Es erscheint mir einfacher eine Batch-Datei über PHP zu starten als eine Exe.
Der Inhalt der Batch-Datei wird nicht überprüft, da PHP nicht bekannt ist, was eine Batch-Datei überhaupt ist. Dies zeigt übrigens auch deutlich die Limits der PHP-internen Restriktionen wie z.B. safe_mode, open_basedir etc.
 
  • Thread Starter Thread Starter
  • #5
Danke, Kugelfisch. Wenn als egal ist, was in der Batch steht, dann ist vielleicht auch egal, was die CMD aufrufen soll. Also kann ich statt der Batch ja auch gleich die Exe direkt aufrufen.

[src=php]passthru ('cmd.exe /r "C:\Path\to\programm.exe" -attribute');[/src]

Dazu muss nur eine cmd.exe im selben Verzeichnis liegen wie das aufrufende PHP.Skript. Soweit korrekt?



*edit*

Mal ne kurze Frage: Angenommen das Öffnen einer CMD wäre von Erfolg gekrönt, könnte ich das offene CMD-Fenster auch tatsächlich per Remote-Desktop sehen oder ist das irgend ein unsichtbarer Hintergrundprozess? Denn den (Miss-)erfolg messe ich die ganze Zeit nur daran, ob sich ein Fenster öffnet, oder nicht. :confused:

[src=php]passthru("cmd.exe /r",$err); echo "FehlerCMD: ".$err;[/src]

Rückgabe FehlerCMD: 0
also doch eigentlich fehlerfrei?!?!

Aber es öffnet sich trotzdem kein Fenster...
 
Zuletzt bearbeitet:
Warum willst du das Programm unbedingt mit CMD aufrufen und nicht direkt, wie in meinem Beispiel?

Das ist ein Hintergrundprozess und läuft unter dem PHP-User.

Gibt's so nen Arma-Server nicht schon irgendwo fertig? Befolgst du eventuell ein Tutorial? Was genau hast du vor?
 
  • Thread Starter Thread Starter
  • #7
Warum willst du das Programm unbedingt mit CMD aufrufen und nicht direkt, wie in meinem Beispiel?
Weil ich dachte, dass die Exe an sich problematisch ist. Und eine Konsole zu starten wird ja wohl (eigentlich) nicht das Problem sein.

Das ist ein Hintergrundprozess und läuft unter dem PHP-User.
Das heißt, die einzige Möglichkeit, zu Prüfen, ob der Prozess gestartet wurde, ist, erstens zu schauen, ob der Server im Spiel erreichbar ist bzw zweitens über irgendwelche Rückgaben mittels PHP???

Wenn ich auf die arma3server.exe per Remote-Desktop auf dem VServer Doppelklicke, sehe ich einen kleinen LoadScreen und dann eine Art Konsole. Kann ich genau dasselbe sehen, wenn PHP den Doppelklick übernimmt. Das ist meine Frage. Denn ich führe bisher immer das PHP-Script aus und beobachte, ob sich diese Game-Server-Konsole öffnet.



Gibt's so nen Arma-Server nicht schon irgendwo fertig? Befolgst du eventuell ein Tutorial? Was genau hast du vor?
Klar, aber das ist mir zu langweilig und die Mission wird im Browser erstellt (klingt so jetzt erstmal sinnlos, aber egal) und dann an den Server geschickt und der Game-Server gestartet. Manuell über Remote-Desktop kann ich ihn ja starten und alles funktioniert bestens. Ich möchte aber, dass das das PHP-Script übernimmt.
 
Zuletzt bearbeitet:
Das heißt, die einzige Möglichkeit, zu Prüfen, ob der Prozess gestartet wurde, ist, erstens zu schauen, ob der Server im Spiel erreichbar ist bzw zweitens über irgendwelche Rückgaben mittels PHP?
Jein, du könntest noch schauen, ob der Port für das Spiel offen ist (so würde ich das machen):
/

Hier mal mit fsockopen(), beachte aber, dass das i.d.R. aus Sicherheitsgründen aus ist:
[src=php]
$host = "localhost";
$port = "2302";
$testconnection = @fsockopen($host, $port);

if (is_resource($testconnection))
{
echo 'Game Port is open.' . "\n";
fclose($testconnection);
}

else
{
echo 'Arma Host not responding.' . "\n";
}[/src]

EDIT: btw, warum machst du das auf nem Windows Server? Arma hat doch auch nen Linux-Server, oder?
 
  • Thread Starter Thread Starter
  • #9
Naja gut, dann scheint es mir noch am sichersten zu sein, einfach ArmA zu starten und zu schauen, ob der Game-Server aufgelistet wird.

Der Windows-Server ist nötig, weil ein spezielles Packprogramm für die Missionen nur als exe existiert. Und die lässt sich ja, wie eingangs beschrieben, hervorragend ausführen. Aber tatsächlich, das sehe ich auch nie per Remote-Desktop. Also probiere ich jetzt noch einmal alle Möglichkeiten durch und kontrolliere, ob der GameServer nun sichtbar wird. Puhh...

Wie kann es aber sein, dass $err immer 1 ist? Das müsste doch Fehler heißen - aber zumindest das Packprogramm arbeitet fehlerfrei und zeigt dennoch 1 an.
 
eine Batch-Datei führt in der Standard-Configuration am Ende immer "Endlocal" aus . Insofern aber am Anfang in der .bat keine lokalisierung durchgeführt wurde schlägt das zurücksetzen fehl.
Der Batch-Interpreter gibt immer den Fehlercode des letzten abgesetzten Befehls zurück (Nicht einen gesamt-Fehlercode oder ähnliches).

Eine .Bat wird zuzuüglich immer Zeilenweise eingelesen + verarbeitet. Das geht sogar soweit das man z.B. mit einem Befehl innerhalb der .bat auf Eingabe warten lasen kann, die .bat bearbeitet, und dann die neu gesetzten Befehle abgearbeitet werden. Daraus erschießt sich dann auch das die ersten Befehle durchaus fehlerfrei gewesen sein können (und der packer funktioniert hat) - dann aber der letzte Befehl nicht erfolgreich war und somit error 1 zurück kommt.

Ein Exit /B am Ende würde das "Problem" beheben da dann immer eine 0 zurück gegeben wird.
Nebenbei würde ein "on error resume next" am Anfang dafür sorgen das sogar nur die eine Zeile mit einem Fehlerhaften Befehl ausgelassen wird - und jeder andere Befehl in der .bat trotzdem ausgeführt wird.
 
  • Thread Starter Thread Starter
  • #11
Ah, okay, das ist gut zu wissen. Danke.

Probehalber habe ich die PHP-Verbindung zu den externen Programm jetzt einmal extrem eingestampft:

Im Ordner der ausführenden PHP-Datei liegt ebenfalls eine cmd.exe.
[src=php]exec('cmd.exe /c dir', $output1, $output2);
print_r($output1);
echo $output2;[/src]

Rückgabe:

Dasselbe passiert, wenn ich statt cmd.exe einfach mal ichrastebaldaus.exe eingebe. Müsste mir PHP jetzt nicht eigentlich eine schöne Ordnerauflistung ausgeben?
 
Zuletzt bearbeitet:
Deine Verzeichnisliste müsste dann aber in $output1 sein :D

Das bei ichrestebaldaus.exe ein errorcode 1 zurück kommt ist doch klar - die gibts ja auch nicht :)
 
  • Thread Starter Thread Starter
  • #13
Sry, Tippfehler. So leicht ist es leider nicht :( (habs oben korrigiert, in der php wars richtig)

Wenn er mir nicht einmal eine Ordnerliste zurückgibt, brauch ich mit Batch und Gameserver ja gar nicht weitermachen.

Was kann der Grund dafür sein, dass das Array bzw der Output1 leer ist?? Gibt es noch grundlegender Debugging-Verfahren, um etwas zu testen?
 
Mit was fährst du denn php - mit IIS oder Apache?

Beim IIS muss der Benutzer unter dem das php-script ausgeführt wird execution Permissions bekommen.
Allgemein benötigt der User der das Batch-Script ausführen soll unter Windows das Recht "logon as Batch-Job"

On Windows, this privilege is granted through the Local or Domain Security Policy. To do this using the Local Security Policy, follow these steps.

In the Control Panel, open Administrative Tools, then Local Security Policy.
Beneath Security Settings, open Local Policies and highlight User Rights Assignment.
Locate Log on as a batch job. Open the properties and add any users that need this right.
When finished, save your changes and close the Local Security Settings window.

Auch habe ich grade nachgelesen das das Ausführende Environment für exec() nicht direkt der Ort der .php Datei ist - sondern im Normalfall ein Standard-Systempfad. Du musst daher den Pfad zur cmd.exe und zur .bat mit vollem Systempfad angeben (und mit doppel \\)
 
Es scheitert meistens an den Quotas.

PHP:
Expand Collapse Copy
exec('"C:\Users\User\batch files\my batch.bat"', $output, $return);

So sollte es gehen. Wenn ich mich recht erinnere, übergibt die exec()-Funktion alles an cmd, so dass man den nicht extra aufrufen muss.
 
  • Thread Starter Thread Starter
  • #16
ich habe jetzt eine test.php erstellt, die nichts anderes macht, als die exec aufzurufen, um alle möglichen Fehlerquellen auszuschließen. Gebe ich nun dort deinen Code ein, Fryk, und korrigiere den Pfad, so lädt die Seite etwa 60 Sekunden und gibt einen Internal Server Error 500 zurück.

Es ist übrigens egal, was ich die Klammern schreibe. Sobald irgendwas mit exec oder passthru steht, kommt Fehler 500. Ich raff das einfach nicht.
[src=php]passthru("cpbo.exe -y -p missions/".$operation_ordner.".Altis",$err);[/src]

Das Ding funktioniert doch auch!
 
Zurück
Oben