Einzelnen Beitrag anzeigen

MStoll

Registriert seit: 15. Nov 2005
131 Beiträge
 
Turbo Delphi für Win32
 
#1

Mit Delphi Code an php.exe schicken

  Alt 23. Nov 2007, 14:55
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
"Man soll nie mehr essen als mit Gewalt reingeht!" (n.n.)
  Mit Zitat antworten Zitat