Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Consolenausgaben LIVE abfangen (https://www.delphipraxis.net/186289-consolenausgaben-live-abfangen.html)

DelTurbo 20. Aug 2015 13:06

Consolenausgaben LIVE abfangen
 
Hi,
Ich versuche seit Stunden den Output eines Commandlineprogramms LIVE abzufragen.
ALLE Beispiele die ich gefunden habe, zeigen die Ausgabe erst an wenn das CommandlineProgramm beendet wird. Also Quasi fertig ist.

Was ich so gefunden habe im Netz ist so ziemlich alles auf dem Beispiel aufgebaut. Das Problem ist das er bei ReadFile sollange wartet bis das SlavePrg fertig ist.

http://delphi.wikia.com/wiki/Capture...altime_To_Memo oder http://stackoverflow.com/questions/2...009-with-vista

Hat jemand eine Idee wie man es "richtig" macht?

Vielen dank im Voraus

Uwe Raabe 20. Aug 2015 13:38

AW: Consolenausgaben LIVE abfangen
 
Zitat:

Zitat von DelTurbo (Beitrag 1312872)
Hi,
Ich versuche seit Stunden den Output eines Commandlineprogramms LIVE abzufragen.

Guckst du hier: Getting output from a shell/dos app into a Delphi app (2. Beispiel in meiner Antwort)

DelTurbo 20. Aug 2015 13:52

AW: Consolenausgaben LIVE abfangen
 
Hi,
erstmal danke für die Antwort. Allerdings habe ich das auch schon probiert. Ich habe viele Probiert. Ich wollte nur nicht alle URLs hier Posten.
Das bleibt leider auch hier stehen und wartet bis das CmdLine Programm zu ende ist.


Delphi-Quellcode:
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);


Kurz zu meinem System:
Windows 7 x64 (Ich hoffe doch es hat nix mit dem 64bit System zu tun.)
Delphi 2007

EDIT: Ich habe es gerade auf 32Bit versucht. Klappt auch nicht.

DelTurbo 20. Aug 2015 14:11

AW: Consolenausgaben LIVE abfangen
 
Was ich auch gesehen habe ist folgender Code. Das ist damit das Programm nicht hängen bleibt, und in der CaptureBar nicht steht "Keine Rückmeldung". Ich denke mal alleine das ist doch ein hinweis darauf das ReadFile an der stelle einfach wartet.

Delphi-Quellcode:
    if CreateProcess(nil,
           PChar(DosApp),
           @Security,
           @Security,
           true,
           NORMAL_PRIORITY_CLASS,
           nil,
           nil,
           start,
           ProcessInfo)
    then
    begin
     repeat
      Apprunning := WaitForSingleObject
                   (ProcessInfo.hProcess,100) ;
      Application.ProcessMessages;
     until (Apprunning <> WAIT_TIMEOUT) ;
      Repeat
        BytesRead := 0;
        ReadFile(ReadPipe,Buffer[0], ReadBuffer,BytesRead,nil) ;
        Buffer[BytesRead]:= #0;
        OemToAnsi(Buffer,Buffer) ;
        AMemo.Text := AMemo.text + String(Buffer) ;
      until (BytesRead < ReadBuffer) ;
   end;

BUG 20. Aug 2015 14:29

AW: Consolenausgaben LIVE abfangen
 
Bist du dir sicher, dass das aufgerufene Programm nicht einfach alles puffert und am Ende komplett ausgibt.

DelTurbo 20. Aug 2015 14:38

AW: Consolenausgaben LIVE abfangen
 
Ja, 100%. Ich habe ein extra zum Testen ein kleines Consolen Programm gemacht.

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  i  :Integer;
begin
  try
  { TODO -oEntwickler -cKonsole Main : Hier Code einfügen }
    for i:=0 to 20 do begin
      Writeln(i);
      Sleep(1000);
    end;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
EDIT: Ich habe sogar das versucht, bis ich gemerkt habe das es für Lazarus ist :(
http://www.delphipraxis.net/1030919-post5.html

nahpets 20. Aug 2015 14:54

AW: Consolenausgaben LIVE abfangen
 
Hallo,

probiere es bitte mal mit dem anhängenden Testprojekt.

In des Unit sbPipes ist eine Komponenten, die eigentlich die von Dir gewünschte Aufgabe erledigen sollte.

Für die Ausgabe kannst Du ihr ein TMemo zuweisen, dann übernimmt die Komponente die Ausgabe, eine Stringliste, auch dann übernimmt die Komponente die Ausgabe in die Stringliste oder Du nutzt das Ereignis OnOutput, dann musst Du selbst für die Ausgabe sorgen.

Im Ereignis OnNotify kannst Du Meldungen der Komponente ausgeben, den Exitcode Deines aufzurufenden Programmes und die Anzahl der gelesenen Bytes in der Ausgabe.

Hab's Beispielprogramm gerade mal getestet, unter Windows XP mit Delphi 7 läuft es.

hathor 20. Aug 2015 15:06

AW: Consolenausgaben LIVE abfangen
 
CaptureConsoleOutput

Delphi-Quellcode:
procedure CaptureConsoleOutput(const ACommand, AParameters: String; AMemo: TMemo);
const CReadBuffer = 2400;
var
   saSecurity: TSecurityAttributes;
   hRead: THandle;
   hWrite: THandle;
   suiStartup: TStartupInfo;
   piProcess: TProcessInformation;
   pBuffer: array[0..CReadBuffer] of ANSIChar;
   dRead: DWord;
   dRunning: DWord;
begin
   saSecurity.nLength := SizeOf(TSecurityAttributes);
   saSecurity.bInheritHandle := True;
   saSecurity.lpSecurityDescriptor := nil;

   if CreatePipe(hRead, hWrite, @saSecurity, 0) then
   begin
     FillChar(suiStartup, SizeOf(TStartupInfo), #0);
     suiStartup.cb := SizeOf(TStartupInfo);
     suiStartup.hStdInput := hRead;
     suiStartup.hStdOutput := hWrite;
     suiStartup.hStdError := hWrite;
     suiStartup.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
     suiStartup.wShowWindow := SW_HIDE;

     if CreateProcess(nil, PChar(ACommand + ' ' + AParameters), @saSecurity,
       @saSecurity, True, NORMAL_PRIORITY_CLASS, nil, nil, suiStartup, piProcess)
       then
     begin
       repeat
         dRunning := WaitForSingleObject(piProcess.hProcess, 100);
         Application.ProcessMessages();
         repeat
           dRead := 0;
           ReadFile(hRead, pBuffer[0], CReadBuffer, dRead, nil);
           pBuffer[dRead] := #0;
           OemToAnsi(pBuffer, pBuffer);
           AMemo.Lines.Add(String(pBuffer));
         until (dRead < CReadBuffer);
       until (dRunning <> WAIT_TIMEOUT);
       CloseHandle(piProcess.hProcess);
       CloseHandle(piProcess.hThread);
     end;
     CloseHandle(hRead);
     CloseHandle(hWrite);
   end;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
CaptureConsoleOutput('cmd.exe', '/c dir c: /s', Memo1);
end;

DelTurbo 20. Aug 2015 15:17

AW: Consolenausgaben LIVE abfangen
 
@nahpets, leider klappt es nicht. Beim laden kommt schon das er TTriggerPipe nicht findet. Ich habe es dann in Privat reingemacht und beim Button1Click erstellt. Dann kann ich es übersetzen und starten, aber leider kommt da nichts.

Das Programm, was in edKommandoZeile steht, wird nicht gestartet. :(

@hathor, das habe ich auch gefunden und probiert. Leider bleibt es wie alle anderen bei ReadFile stehen bis das aufgerufene Programm fertig ist.

Gruß und danke schonmal

hathor 20. Aug 2015 15:28

AW: Consolenausgaben LIVE abfangen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Bei mir läuft's mit XE7 und WIN8.1.

Mach doch bitte ein COPY&PASTE und teste es!

Hast Du die vertikale Scrollbar beim Memo aktiviert?

Ich habe mal die EXE angefügt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:07 Uhr.
Seite 1 von 3  1 23      

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