![]() |
Mit Delphi Code an php.exe schicken
Hallo,
ich möchte gerne mit Hilfe von PHP Code parsen, den ich in meiner Anwendung als String zur Verfügung habe, und die Ausgabe wieder entgegennehmen. Das mit der Ausgabe entgegennehmen funktioniert soweit auch ganz gut, da gibt's ja hier im Forum auch einige Threads und Code dazu. Allerdings funktioniert das Senden meines Codes an stdin der php.exe nicht. Die nimmt ja solange Code entgegen, bis ein Strg+Z kommt. Klappt auch in der Konsole von Hand soweit alles prima. Wenn ich allerdings die Funktion GetConsoleOutput benutze (die ich mir wie folgt angepasst habe), bleibt Delphi beim ReadFile hängen:
Delphi-Quellcode:
Ich muss zugeben, dass ich mich mit Prozessen und Pipes noch nicht viel beschäftigt habe und daher auch nicht weiß, an welcher Stelle ich das WriteFile benutzen soll.
function GetConsoleOutput(const Command, stdin : String; var Output, Errors: TStringList): Boolean;
var StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; SecurityAttr: TSecurityAttributes; PipeOutputRead: THandle; PipeOutputWrite: THandle; PipeInputRead: THandle; PipeInputWrite: THandle; PipeErrorsRead: THandle; PipeErrorsWrite: THandle; Succeed: Boolean; Buffer: array [0..255] of Char; NumberOfBytesRead, NumberOfBytesWritten: DWORD; Stream: TMemoryStream; inputtext : string; begin //Initialisierung ProcessInfo FillChar(ProcessInfo, SizeOf(TProcessInformation), 0); //Initialisierung SecurityAttr FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0); SecurityAttr.nLength := SizeOf(SecurityAttr); SecurityAttr.bInheritHandle := true; SecurityAttr.lpSecurityDescriptor := nil; //Pipes erzeugen CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0); CreatePipe(PipeInputRead, PipeInputWrite, @SecurityAttr, 0); CreatePipe(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0); //Initialisierung StartupInfo FillChar(StartupInfo, SizeOf(TStartupInfo), 0); StartupInfo.cb :=SizeOf(StartupInfo); StartupInfo.hStdInput := PipeInputRead; StartupInfo.hStdOutput := PipeOutputWrite; StartupInfo.hStdError := PipeErrorsWrite; StartupInfo.wShowWindow := sw_Hide; StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; if CreateProcess( nil, PChar(command), nil, nil, true, CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo) then begin result:=true; //Write-Pipes schließen CloseHandle(PipeOutputWrite); CloseHandle(PipeErrorsWrite); //Eingabe Write-Pipe schreiben inputtext := stdin + #$A#13#10; while length(inputtext) > 0 do begin WriteFile(PipeInputRead, inputtext[1], 1, NumberOfBytesWritten, nil); WriteFile(PipeInputWrite, inputtext[1], 1, NumberOfBytesWritten, nil); Delete(inputtext, 1, 1); end; CloseHandle(PipeInputWrite); //Ausgabe Read-Pipe auslesen Stream := TMemoryStream.Create; try while true do begin succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil); // Hier bleibt's dann hängen! if not succeed then break; Stream.Write(Buffer, NumberOfBytesRead); end; Stream.Position := 0; Output.LoadFromStream(Stream); finally Stream.Free; end; CloseHandle(PipeOutputRead); //Fehler Read-Pipe auslesen Stream := TMemoryStream.Create; try while true do begin succeed := ReadFile(PipeErrorsRead, Buffer, 255, NumberOfBytesRead, nil); if not succeed then break; Stream.Write(Buffer, NumberOfBytesRead); end; Stream.Position := 0; Errors.LoadFromStream(Stream); finally Stream.Free; end; CloseHandle(PipeErrorsRead); CloseHandle(PipeInputRead); WaitForSingleObject(ProcessInfo.hProcess, INFINITE); CloseHandle(ProcessInfo.hProcess); end else begin result:=false; CloseHandle(PipeOutputRead); CloseHandle(PipeOutputWrite); CloseHandle(PipeInputRead); CloseHandle(PipeInputWrite); CloseHandle(PipeErrorsRead); CloseHandle(PipeErrorsWrite); end; end; Ich habe jetzt Stunden hier gesucht und die verschiedenen Varianten ausprobiert, die zum Thema Konsolenanwendung benutzen existieren, aber noch nichts gefunden, was mit der php.exe funktioniert. Sie wird gestartet und es passiert nichts mehr weiter. Hat dafür jemand ne Lösung oder wenigstens Ansätze? Danke und Gruß Michael |
Re: Mit Delphi Code an php.exe schicken
Hallo.
Ich weiß leider nicht, was Pipes sind, aber wieso speicherst du deine PHP-Datei nicht temporär ab und gibst den temporären Dateinamen als Argument für php.exe? Gruß blackdrake |
Re: Mit Delphi Code an php.exe schicken
Das mach ich bislang so, ist allerdings eine meiner Meinung nach unsaubere Lösung, da es ja schließlich für Konsolenanwendungen Eingabe- und Ausgabe-Möglichkeiten gibt. Und die muss man doch auch irgendwie unter Delphi nutzen können.
|
Re: Mit Delphi Code an php.exe schicken
Wo kommt denn der Code her? Ich halte ihn für, gelinde gesagt, nicht ideal. Denn ein ReadFile-Aufruf ist standardmäßig blockierend, d.h. es wird gewartet, bis so viele Daten wie gefordert in der Pipe sind.
|
Re: Mit Delphi Code an php.exe schicken
geht das mit standard in, nicht normal so...
Delphi-Quellcode:
program mist(input, output);
{$APPTYPE CONSOLE} uses SysUtils; var s: string; begin while not eof(input) do begin readln(input, s); writeln(output, '> das ist ''n mist, gelle: ', s ); end; end. |
Re: Mit Delphi Code an php.exe schicken
Die Funktion kommt (ohne meine Anpassungsversuche bzgl. stdin) aus diesem Forum (Beitrag weiß ich leider nicht mehr genau, aber die Suche hilft). Dieser Code funktioniert soweit, dass man den Output einer beliebigen Konsolenanwendung bekommt. Und dass ReadFile wartet, ist auch kein Problem, da ich ja die Ausgabe von php haben will, nachdem es fertig geparst hat. Mein Problem ist, dass der PHP-Code anscheinend nicht bei auf dem stdin von PHP ankommt.
@grenzgaenger: Meine Delphi-Anwendung ist keine Konsolen-Anwendung. Sie soll mit der Konsolenanwendung php über Pipes kommunizieren. |
Re: Mit Delphi Code an php.exe schicken
Ich werfe einfach mal
![]() mfg, Björn |
Re: Mit Delphi Code an php.exe schicken
Außerdem geht da auch der umgekehrte Weg, nämlich die Erweiterung von php mit Delphi
|
Re: Mit Delphi Code an php.exe schicken
Vielen Dank für eure Vorschläge. Aber geht es euch nicht auch so, dass ihr, wenn ihr denkt, dass etwas gehen muss, es auch mal so am laufen haben wollt? Ich meine, man muss doch mit Delphi mit der php.exe kommunizieren können, wenn ich ein Konsolenfenster öffne, php eingebe, Enter drücke, PHP-Code eingebe, Strg+Z und nochmal Enter drücke, dann geht das doch auch.
Vielleicht hat ja jemand ne Idee, wie man das Problem lösen statt umgehen kann. Danke schonmal :) |
Re: Mit Delphi Code an php.exe schicken
Zitat:
.... .... ... dann hast du auch kein standard in... also, vergiss diesen weg. und such dir 'n anderes spielzeug aus... :drunken: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:43 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz