Exe-Datei aufrufen
Konrad
- php
Hallo,
Der Aufruf einer exe-Datei erfolgt ja über
exec ( string $befehl [, array $ausgabe [, int $return_var ]] )
d.h. exec kann mehrere Parameter haben.
Wie rufe ich nun ein Programm auf, das ebenfalls Parameter hat, also z.B.
prog.exe -w -l
So ist es ja wohl nicht korrekt:
exec ( string $befehl -w -l [, array $ausgabe [, int $return_var ]] )
Die Antwort hast du dir selber doch schon fast gegeben.
$befehl = 'prog.exe -w -l';
Hi,
danke für den Tipp.
Ich habe nun den exe-Befehl in einer Funktion f1, die ich in einer Schleife mehrmals aufrufe.
Das Ergebnis ist nun immer gleich, obwohl es unterschiedlich sein müsste.
Wenn ich in der Schleife alle Aufrufe der Funktion f1 bis auf jeweils einen (z.B. den 1. den 2, ,...) unterdrücke, so ist das Ergebnis jeweils korrekt.
Woran kann dies liegen?
Moin,
Ich habe nun den exe-Befehl in einer Funktion f1, die ich in einer Schleife mehrmals aufrufe.
Wie sieht denn der Code aus? Wir können hier nur raten.
Das Ergebnis ist nun immer gleich, obwohl es unterschiedlich sein müsste.
Wenn ich in der Schleife alle Aufrufe der Funktion f1 bis auf jeweils einen (z.B. den 1. den 2, ,...) unterdrücke, so ist das Ergebnis jeweils korrekt.
Grüße Marco
Hallo,
die Sache sieht jetzt etwas einfacher (oder komplizierter?) aus.
Es liegt nicht an der Funktion.
Hier das Beispiel:
<?php
$programmPfad = 'D:/CSDiff/CSDiff.exe';
$DiffDateiPfad = 'F:\tmp\DiffOutput.txt';
$datei1 = 'd:\test\a.php'; // a.php != b.php, a.php == c.php
$datei2 = 'd:\test\b.php';
$datei3 = 'd:\test\c.php';
$handle = fopen($DiffDateiPfad, 'w');
fclose($handle); // Leere Datei erstellen
print (filesize ($DiffDateiPfad)); // ==> 0
echo "<br>";
$exec = $programmPfad . ' /Od' . $DiffDateiPfad . ' ' . $datei1 . ' ' . $datei2;
exec ($exec); // Ergebnis 0, wenn Dateien identisch, > 0, wenn verschieden
print (filesize ($DiffDateiPfad)); // sollte != 0 sein
?>
Auch wenn die Datei ($DiffDateiPfad = 'F:\tmp\DiffOutput.txt';) einen Inhalt hat, liefert filesize den Wert 0.
Wenn ich nach Beendigung des Programms dieses Programm:
<?php
$DiffDateiPfad = 'F:\tmp\DiffOutput.txt';
print (filesize ($DiffDateiPfad)); // ==> 0
?>
aufrufe, wird mir die Größe der Datei (>0) richtig angezeigt.
Vermutung: Datei ist noch nicht geschlossen, wenn das sizeof durchgeführt wird.
Wie kann ich dies ändern?
Danke
Konrad
Moin,
$handle = fopen($DiffDateiPfad, 'w');
fclose($handle); // Leere Datei erstellen
Das geht einfacher mit
file_put_contents($DiffDateiPfad, "");
$exec = $programmPfad . ' /Od' . $DiffDateiPfad . ' ' . $datei1 . ' ' . $datei2;
Hier fehlt meiner Meinung nach ein Leerzeichen nach /Od
print (filesize ($DiffDateiPfad)); // sollte != 0 sein
Auch wenn die Datei ($DiffDateiPfad = 'F:\tmp\DiffOutput.txt';) einen Inhalt hat, liefert filesize den Wert 0.
Hast du mal probiert die Datei einzulesen, um zu sehen, ob er wirklich die richtige hat?
Sollte hingegen die Datei wirklich noch geöffnet sein, dann sollte filesize einen Fehler werfen, den du aber nicht auswertest. Du könntest testweise folgendes an dieser Stelle probieren:
if( filesize($DiffDateiPfad) === false ) echo ("Ein Fehler ist beim Auslesen der Dateigröße aufgetreten");
else echo ("Wert kann ausgelesen werden.");
Vermutung: Datei ist noch nicht geschlossen, wenn das sizeof durchgeführt wird.
Wie kann ich dies ändern?
Erstmal ist es eine Vermutung, die du bestätigen solltest. PHP wartet aber eigentlich, bis das Programm beendet ist, welches mit exec()
aufgerufen wurde, bevor es mit der Ausführung fortfährt.
Sollte es wirklich noch an einem Dateilock liegen, kannst du auf die Verfügbarkeit der Datei prüfen.
while(fopen($DiffDateiPfad)===false) {}
Grüße Marco
$exec = $programmPfad . ' /Od' . $DiffDateiPfad . ' ' . $datei1 . ' ' . $datei2;
Hier fehlt meiner Meinung nach ein Leerzeichen nach /Od
Nein, das ist korrekt.
print (filesize ($DiffDateiPfad)); // sollte != 0 sein
Auch wenn die Datei ($DiffDateiPfad = 'F:\tmp\DiffOutput.txt';) einen Inhalt hat, liefert filesize den Wert 0.Hast du mal probiert die Datei einzulesen, um zu sehen, ob er wirklich die richtige hat?
Ja, sie ist je nach Ergebnis des Vergleich leer oder hat einen Inhalt.
Sollte hingegen die Datei wirklich noch geöffnet sein, dann sollte filesize einen Fehler werfen, den du aber nicht auswertest. Du könntest testweise folgendes an dieser Stelle probieren:
if( filesize($DiffDateiPfad) === false ) echo ("Ein Fehler ist beim Auslesen der Dateigröße aufgetreten");
else echo ("Wert kann ausgelesen werden.");
>
Habe dies jetzt 3-mal angegeben. Vor dem Erstellen der Datei kommt wie erwartet "Ein Fehler..."
Nach der Dateianlage (leer) kommt kein Fehler und nach der Ausführung des exec kommt ebenfalls kein Fehler.
Die filesize wird aber mit 0 ausgegeben, obwohl die Datei gefüllt ist.
Erst wenn ich jetzt in einem neuen php-Programm die filesize der selben(!) Datei noch einmal abfrage, ist sie korrekt.
> Sollte es wirklich noch an einem Dateilock liegen, kannst du auf die Verfügbarkeit der Datei prüfen.
>
Und jetzt kommt für mich etwas sehr Sonderbares!
Bei
`while(fopen($DiffDateiPfad,'r')===false) {echo "Fehler"}`{:.language-php}
kommt kein "Fehler" und filesize ist nach wie vor 0
aber bei
`while(fopen($DiffDateiPfad,'r')===false) {echo "Fehler"}`{:.language-php}
kommt ebenfall kein "Fehler" aber filesize hat den korrekten Wert >0
Hängt dies am Maya-Kalender? Sollte ich warten bis zum morgigen Weltuntergang?
Gruß
Wolfgang
Bei
while(fopen($DiffDateiPfad,'r')===false) {echo "Fehler"}
kommt kein "Fehler" und filesize ist nach wie vor 0
aber bei
while(fopen($DiffDateiPfad,'r')===false) {echo "Fehler"}
Hier muss es heißen:
while(fopen($DiffDateiPfad,'r')==false) {echo "Fehler"}
kommt ebenfall kein "Fehler" aber filesize hat den korrekten Wert >0
Hallo,
$handle = fopen($DiffDateiPfad, 'w');
fclose($handle); // Leere Datei erstellen
Das geht einfacher mit
file_put_contents($DiffDateiPfad, "");
und noch einfacher mit
touch($DiffDateiPfad);
Vermutung: Datei ist noch nicht geschlossen, wenn das sizeof durchgeführt wird.
Das allein ist nicht der Knackpunkt. PHP versucht, File-Operationen zu "optimieren", indem es den Zustand bestimmter Dateieigenschaften speichert. Normalerweise ist das kein Problem; falls sich aber Eigenschaften von Dateien während des Scriptablaufs ändern und dann erneut abgefragt werden, bekommt man "kalten Kaffee".
Wie kann ich dies ändern?
Wahrscheinlich mit clearstatcache().
Ciao,
Martin
Hallo,
mit clearstatcache() funktioniert es!
Vielen Dank!
Hallo,
Das geht einfacher mit
file_put_contents($DiffDateiPfad, "");
und noch einfacher mit
touch($DiffDateiPfad);
Allerdings ist file_put_contents etwa doppelt so schnell wie touch
Siehe hier
Gruß
Konrad
Hallo,
Allerdings ist file_put_contents etwa doppelt so schnell wie touch
das wäre aber überraschend und für mich nicht logisch nachvollziehbar.
Ich bin mir nicht sicher, ob ich diesem Beitrag wirklich trauen mag. Erstens ist er zwei Jahre alt, eine aktuelle PHP-Version könnte sich schon wieder anders verhalten; zweitens spielen auch da wohl viele Cache-Effekte eine Rolle; drittens ist es sehr von der Implementation im Betriebssystem abhängig.
Andererseits reden wir hir von etwa 1ms vs. 2ms bei einer Operation, die man normalerweise nur einzeln durchführt und nicht vielfach in einer Schleife. Mir wäre da die einfachere Schreibweise von touch() sympathischer. Wenn ich den Code in zwei Jahren mal wieder anfassen müsste und file_get_contents() sehe, würde ich mich bestimmt fragen, warum zum Geier ich an der Stelle "nichts" in die Datei schreiben wollte. Wollte ich die Datei etwa "leeren"?
Es gibt nämlich noch einen bösen Fallstrick, der für touch() spricht: Die Variante mit file_put_contents() löscht den Dateiinhalt (setzt die Dateilänge auf 0), wenn die Datei bereits existieren sollte!
Ciao,
Martin
Ich bin mir nicht sicher, ob ich diesem Beitrag wirklich trauen mag. Erstens ist er zwei Jahre alt, eine aktuelle PHP-Version könnte sich schon wieder anders verhalten; zweitens spielen auch da wohl viele Cache-Effekte eine Rolle; drittens ist es sehr von der Implementation im Betriebssystem abhängig.
Außerdem fehlen jegliche Angaben zur ausführenden Umgebung. Zum Beispiel ist nicht bekannt, welches Programm die Laufzeiten gemessen hat. Der Stichproben Umfang ist außerdem sehr niedrig gewählt.