AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi ReadFileEx Callback wird nicht aufgerufen
Thema durchsuchen
Ansicht
Themen-Optionen

ReadFileEx Callback wird nicht aufgerufen

Ein Thema von Namenloser · begonnen am 31. Jan 2010 · letzter Beitrag vom 6. Feb 2010
 
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#1

ReadFileEx Callback wird nicht aufgerufen

  Alt 31. Jan 2010, 21:50
Hallo,

ich habe wieder ein Problem

Ich möchte gerne die Konsolenausgabe eines Programms in ein Memo umleiten - gut, das gab's hier schon oft. Allerdings brauche ich die Ausgabe schon, während das Programm noch läuft, und nicht erst am Ende. Dafür habe ich leider keine fertige Lösung gefunden, weshalb ich angefangen habe, selbst eine zu basteln, auf Basis des Codes aus der CodeLib.

Zuerst habe ich in der Schleife entsprechende Ereignisse ausgelöst, was auch ganz gut funktionierte. Aber da ich eine allgemeingültige Lösung wollte, die auch StdErr mitauswertet, musste ich eine andere Lösung finden, da das Auslesen von StdErr immer das ganze Programm blockierte, wenn keine Fehler ausgegeben wurden. Die Idee war jetzt, die API-Funktion ReadFile durch die asynchrone Funktion ReadFileEx zu ersetzen, um zu verhindern, dass eine Pipe die andere blockiert. Also habe ich alles, was für das asynchrone auslesen einer Pipe nötig ist, in die Klasse TPipeReader gekapselt. Soweit so gut.

Problem: Es funktioniert nicht. Um genau zu sein funktioniert es einmal, bei der ersten Ausgabe die das Programm tätigt... danach wird das Callback nicht mehr aufgerufen, obwohl der Puffer des Readers sich füllt.

Hier mal der zurechtgestutzte Code:

Delphi-Quellcode:
procedure TConsoleRedirector.Run(Command: string);
var
  CreationFlags: DWORD;
  ProcessInfo: TProcessInformation;
  SecurityAttr: TSecurityAttributes;
  StartupInfo: TStartupInfo;
begin
    { ... }
    // Pipe-Reader seine Lesepipe zuweisen und lauschen
    FOutputReader.Pipe := PipeOutputRead;
    FOutputReader.Listen;

// Mit diesen Zeilen friert das Programm leider komplett ein:
// FErrorReader.Pipe := PipeErrorsRead;
// FErrorReader.Listen;

    // Schleife ausführen solange gestarteter Prozess läuft
    // Der letzte Parameter gibt an, dass an dieser Stelle das Callback
    // ausgeführt werden kann
    while not (WaitForSingleObjectEx(ProcessInfo.hProcess, 0, True) in
      [WAIT_OBJECT_0, WAIT_ABANDONED]) do
    begin
      Application.ProcessMessages;
    end;
    { ... }
end;

procedure PipeReadCallback(ErrorCode: dword; NumberOfBytesTransfered: dword;
  Overlapped: POverlapped); stdcall;
var
  PipeReadBuffer: TPipeReader;
begin
  WriteLn(Format('PipeReadCallback %d, %d', [ErrorCode, NumberOfBytesTransfered]));

  // In hEvent dürfen laut MSDN Zusatzdaten gespeichert werden, da es von ReadFileEx nicht berücksichtigt wird
  PipeReadBuffer := TPipeReader(Overlapped^.hEvent);
  PipeReadBuffer.FBytesRead := NumberOfBytesTransfered;
  PipeReadBuffer.DoRead;
end;

{ TPipeBuffer }

procedure TPipeReader.DoRead;
begin
  if Assigned(FOnRead) then
    FOnRead(Self, Data);
  // Auf Folgedaten warten
  Listen;
end;

procedure TPipeReader.Listen;
begin
  if ReadFileEx(Pipe, Buffer, BufferSize, @FOverlapped, @PipeReadCallback) then
    WriteLn('ReadFileEx ok')
  else
    WriteLn('ReadFileEx NOT OK');
end;

end.
Wie ich bereits sagte funktioniert das ganze genau einmal. Wenn man jetzt z.B. das Kommando "cmd /K dir C:" ausführt, erhält man die erste ausgegebene Zeile, aber der Rest fehlt. Danach friert das Programm ein, weil es darauf wartet, dass das aufgerufene Programm beendet wird, aber das aufgerufene Programm wiederum darauf wartet, dass die Pipe geleert wird, was nicht passiert, da das Callback ja aus unerfindlichen Gründen nicht aufgerufen wird. Bei meinem Brainfuck-JIT-Compiler, wofür ich das ganze eigentlich geschrieben habe, kann ich so nur das erste Zeichen empfangen.

Was mache ich falsch?

Vielen Dank.
Angehängte Dateien
Dateityp: zip consoleredirector_145.zip (292,2 KB, 12x aufgerufen)
  Mit Zitat antworten Zitat
 


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 19:21 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