Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Mit Delphi Code an php.exe schicken (https://www.delphipraxis.net/103883-mit-delphi-code-php-exe-schicken.html)

MStoll 23. Nov 2007 13:55


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:
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 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.
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

blackdrake 23. Nov 2007 14:48

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

MStoll 23. Nov 2007 17:02

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.

Apollonius 23. Nov 2007 17:07

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.

grenzgaenger 23. Nov 2007 17:26

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.

MStoll 23. Nov 2007 19:23

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.

arbu man 23. Nov 2007 21:02

Re: Mit Delphi Code an php.exe schicken
 
Ich werfe einfach mal php4delphi. Das ist viel besser als nur die Konsole benutzen, kann kann eigene Funktionen etc. verwenden.

mfg, Björn

mkinzler 23. Nov 2007 21:04

Re: Mit Delphi Code an php.exe schicken
 
Außerdem geht da auch der umgekehrte Weg, nämlich die Erweiterung von php mit Delphi

MStoll 23. Nov 2007 21:51

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 :)

grenzgaenger 23. Nov 2007 22:27

Re: Mit Delphi Code an php.exe schicken
 
Zitat:

Zitat von MStoll
@grenzgaenger:
Meine Delphi-Anwendung ist keine Konsolen-Anwendung. Sie soll mit der Konsolenanwendung php über Pipes kommunizieren.

gut... nur, wenn du keine konsolen anwendung hast....

....
....


... 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.
Seite 1 von 2  1 2      

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