AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Mit Delphi Code an php.exe schicken

Ein Thema von MStoll · begonnen am 23. Nov 2007 · letzter Beitrag vom 26. Nov 2007
Antwort Antwort
Seite 1 von 2  1 2      
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
blackdrake

Registriert seit: 22. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#2

Re: Mit Delphi Code an php.exe schicken

  Alt 23. Nov 2007, 15:48
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
Daniel Marschall
  Mit Zitat antworten Zitat
MStoll

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

Re: Mit Delphi Code an php.exe schicken

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

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Mit Delphi Code an php.exe schicken

  Alt 23. Nov 2007, 18:07
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.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
grenzgaenger
(Gast)

n/a Beiträge
 
#5

Re: Mit Delphi Code an php.exe schicken

  Alt 23. Nov 2007, 18:26
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.
  Mit Zitat antworten Zitat
MStoll

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

Re: Mit Delphi Code an php.exe schicken

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

Registriert seit: 3. Nov 2004
Ort: Krefeld
1.108 Beiträge
 
Delphi 7 Professional
 
#7

Re: Mit Delphi Code an php.exe schicken

  Alt 23. Nov 2007, 22:02
Ich werfe einfach mal php4delphi. Das ist viel besser als nur die Konsole benutzen, kann kann eigene Funktionen etc. verwenden.

mfg, Björn
Björn
>> http://bsnx.net <<
Virtual DP Stammtisch v1.0"iw" am 19.09.2007 - ich war dabei!
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: Mit Delphi Code an php.exe schicken

  Alt 23. Nov 2007, 22:04
Außerdem geht da auch der umgekehrte Weg, nämlich die Erweiterung von php mit Delphi
Markus Kinzler
  Mit Zitat antworten Zitat
MStoll

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

Re: Mit Delphi Code an php.exe schicken

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

n/a Beiträge
 
#10

Re: Mit Delphi Code an php.exe schicken

  Alt 23. Nov 2007, 23:27
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...
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz