Einzelnen Beitrag anzeigen

Jörn

Registriert seit: 5. Sep 2003
Ort: Helmstedt
312 Beiträge
 
#1

Commandline-Tool in Delphi-Prog umleiten

  Alt 20. Jan 2004, 17:12
Mit folgender Prozedur (nich mal von mir *gg*) leite ich die Ausgabe aus einem cmd-tool in ein memo um:

Delphi-Quellcode:
procedure CaptureDosCmd(command:String;OutputMemo:TMemo);
const
  CaptureBufferSize = 2500;
var
  SecAttrib : TSecurityAttributes;
  ReadPipe,writePipe : THandle;
  Startup : TStartUpInfo;
  ProcessInfo : TProcessInformation;
  CaptureBuffer : Pchar;
  BytesRead : DWord;
  WaitHandle : DWord;
begin
  OutPutMemo.Lines.clear;
  OutputMemo.lines.add('Starte "'+command+'"');
  With SecAttrib do
  begin
    nlength := SizeOf(TSecurityAttributes);
    binherithandle := true;
    lpsecuritydescriptor := nil;
  end;
  if Createpipe (ReadPipe, writePipe, @SecAttrib, 0) then
  begin
    CaptureBuffer := AllocMem(CaptureBufferSize + 1);
    FillChar(Startup,Sizeof(Startup),#0);
    Startup.cb := SizeOf(Startup);
    Startup.hStdOutput := writePipe;
    Startup.hStdInput := ReadPipe;
    Startup.dwFlags := STARTF_USESTDHANDLES +
                           STARTF_USESHOWWINDOW;
    Startup.wShowWindow := SW_HIDE;

    if CreateProcess(nil,
      PChar(command),
      @SecAttrib,
      @SecAttrib,
      true,
      NORMAL_PRIORITY_CLASS,
      nil,
      nil,
      Startup,
      ProcessInfo) then
    begin
      repeat
        WaitHandle := WaitForSingleObject( ProcessInfo.hProcess,100);
        Application.ProcessMessages;
      until (WaitHandle <> WAIT_TIMEOUT) or application.terminated;
      if not application.terminated then
      Repeat
        BytesRead := 0;
        ReadFile(ReadPipe,CaptureBuffer[0],CaptureBufferSize,BytesRead,nil);
        CaptureBuffer[BytesRead]:= #0;
        OemToAnsi(CaptureBuffer,CaptureBuffer);
        OutputMemo.Text := OutputMemo.Text+String(CaptureBuffer);
      until (BytesRead < CaptureBufferSize);
      end else OutPutMemo.lines.add('Operation wurde abgebrochen!');
    FreeMem(CaptureBuffer);
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ReadPipe);
    CloseHandle(writePipe);
  end else OutPutMemo.lines.add('Konnte Kommando nicht starten, Fehler: #'+
  inttostr(getlasterror));
end;
Wenn ich etwas schnelles wie zB dir C:\ aufrufe, ist das auch gar kein Problem. Ich möchte aber einen alten cmd-Packer nutzen und dafür eine GUI schreiben. Doch bei solch "langen" Laufzeiten funktioniert das ganze nicht bzw man sieht den Fortschritt nicht weil

Delphi-Quellcode:
        repeat
        WaitHandle := WaitForSingleObject( ProcessInfo.hProcess,100);
        Application.ProcessMessages;
      until (WaitHandle <> WAIT_TIMEOUT) or application.terminated;
hier gewartet wird, bis das Programm beendet wird, dann wird der Inhalt des cmds in das Memo kopiert. Die 100 ist quasi der timeout (bin ich der Meinung). Alles was darüber hinausgeht, funktioniert daher nicht. Aufruf der Funktion wäre zB

CaptureDosCmd(cmd+' /c dir '+par,Memo1); Nun weiss ich aber nicht, wie ich erreichen kann, das entweder alles in "Echtzeit" in das Memo geschrieben wird, oder das nach einer beliebig langen Laufzeit das Memo gefüllt wird.

Ich hoffe ich habe das ausreichend erläutert. Schon mal vielen Dank für eure Hilfe

MfG
  Mit Zitat antworten Zitat