Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Ein- / Ausgabe einer DOS Anwendung umleiten (https://www.delphipraxis.net/104472-ein-ausgabe-einer-dos-anwendung-umleiten.html)

criminal 4. Dez 2007 19:18


Ein- / Ausgabe einer DOS Anwendung umleiten
 
Hallo,

also ich brauche ein Programm, welches die Eingabe meines Delphiprogrammes in ein Programm in einem Dosfenster umleiten, und eben die Ausgabe an das Delphiprogramm zurückgibt.
Die Eingabe funktioniert auch, die hab' ich folgendermassen gemacht:
Delphi-Quellcode:
Mit FindWindow ein Handle auf das DOS-Fenster erstellt, dessen Titelzeile im Eingabefeld edit2 steht
W := FindWindow(NIL, PChar(edit2.text));
Und nun einen Befehl an das DOS-Fenster zu schicken benutze ich den PostMessage Befehl
Delphi-Quellcode:
     text := upperCase(text);
     for i := 1 to length(text) do
          PostMessage(W, wm_KeyDown, VKKeyScan(text[i]), 0);
     PostMessage(W, wm_KeyDown, VK_Return, 0);
Oki, so weit so gut, jetzt brauch ich allerdings die Ausgabe des DOS-Fensters...
Anhand einer Ausgabeumleitung in eine Datei (>) geht es leider nicht, da die Ausgabe während des Ablaufs geändert wird und ich nicht mit Delphi auf die Datei zugreifen kann, solange mein DOS-Programm noch läuft.

Hoffe auf baldige Antwort(en)

[edit=SirThornberry]Delphi-Tags gesetzt - nächstes mal bitte selbst machen - Mfg, SirThornberry[/edit]

MrKnogge 4. Dez 2007 19:55

Re: Ein- / Ausgabe einer DOS Anwendung umleiten
 
Hi

Delphi-Quellcode:
function GetConsoleOutput(const Command: String; var Output, Errors: TStringList): Boolean;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  SecurityAttr: TSecurityAttributes;
  PipeOutputRead: THandle;
  PipeOutputWrite: THandle;
  PipeErrorsRead: THandle;
  PipeErrorsWrite: THandle;
  Succeed: Boolean;
  Buffer: array [0..255] of Char;
  NumberOfBytesRead: DWORD;
  Stream: TMemoryStream;
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(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0);

  //Initialisierung StartupInfo
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  StartupInfo.cb:=SizeOf(StartupInfo);
  StartupInfo.hStdInput := 0;
  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);

    //Ausgabe Read-Pipe auslesen
    Stream := TMemoryStream.Create;
    try
      while true do begin
        succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil);
        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);

    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
    CloseHandle(ProcessInfo.hProcess);
  end
  else begin
    result:=false;
    CloseHandle(PipeOutputRead);
    CloseHandle(PipeOutputWrite);
    CloseHandle(PipeErrorsRead);
    CloseHandle(PipeErrorsWrite);
  end;
end;
Aufrufbeispiel:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var output, errors: TStringList;
begin
  output:=TStringList.Create;
  try
    errors:=TStringList.Create;
    if GetConsoleOutput('cmd /c dir c:\', output, errors) then
      Memo1.Lines.AddStrings(output);
  finally
    output.free;
    errors.free;
  end;
end;

chaosben 5. Dez 2007 05:55

Re: Ein- / Ausgabe einer DOS Anwendung umleiten
 
Oder ... einen Tick einfacher: ConsoleTools (Inklusive 1 known issue)


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:58 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