Einzelnen Beitrag anzeigen

ArneH

Registriert seit: 9. Apr 2006
7 Beiträge
 
#1

Cmd.exe über Pipes steuern - Probleme

  Alt 9. Apr 2006, 01:18
Hallo!

Programmbeschreibung:
Ich habe ein Programm geschrieben, dass nicht nur (wie bei vielen Beispielen aus dem Forum hier) die Ausgabe einer Konsolen-Anwendung via Pipe auslesen kann, sondern auch die interaktive Kommunikation mit einem solchen Prozess erlaubt. Beispielhaft habe ich hier die "cmd.exe" verwendet.

http://www.arnehaak.de/console-control/screenshot.png
(Ich hoffe es ist OK, dass ich diesen Screenshot (23 KB) hier einbinde.)

Die Bedienung ist eigentlich selbsterklärend. Klickt man auf "Start", so wird eine neue Instanz der "cmd.exe" (muss im Moment noch in "c:\windows\system32\cmd.exe" liegen) gestartet, und man kann sie bedienen, fast so die normale Konsole von Windows. Unten werden dann noch Debug-Infos ausgegeben, das was dort angezeigt wird ist jedoch schon gefilter (Zeichensätze umgewandelt, Füllzeichen entfernt, Zeilenumbrüche korrigiert). Das ganze soll später nochmal stark ausgebaut werden.


Problem:
Meistens klappt alles schon so, wie ich mir das vorstelle, jedoch hakt die Ausgabe des öften, beispielsweise wenn man mit "dir" den Verzeichnisinhalt anzeigen lässt, oder wenn man - wie auf dem Screenshot - einen Ping macht. Das kann 20x gutgehen, und dann hakt es irgendwann: Zuerst steht nichts dort, bestätigt man nochmal mit Return, dann steht dort "Mehr?", bestätigt man nochmal, dann erscheint dort die Ausgabe, die eigentlich erwartet wurde.
Was läuft da falsch?


Code:
Den (vermutlich) wichtigen Code habe ich mal herauskopiert:

Erstmal ein paar Variablen, die im anschließenden Code-Sample genutzt werden:

Delphi-Quellcode:
buf: Array[0..1023] of Char; //i/o buffer
read_stdout: HWND; //pipe handle
bread: Cardinal; //bytes read
avail: Cardinal; //bytes available

Und hier der eigentliche Code, der noch nicht 100%ig läuft:

Delphi-Quellcode:
//Haupt-Programmschleife (im Thread)
begin
  bzero(buf);

  if avail > 1023 then
    while bread >= 1023 do
      begin
        ReadFile(read_stdout, buf, 1023, bread, nil); //read the stdout pipe
        MainForm.CLBack(BufferToString(buf));

        bzero(buf);
      end
  else
    begin
      ReadFile(read_stdout, buf, 1023, bread, nil);
      MainForm.CLBack(BufferToString(buf));
    end;
end;

Download:
Das Programm könnt ihr hier zum Testen runterladen:
http://www.arnehaak.de/console-contr...ntrol_test.exe


Bin für jegliche Tipps dankbar!

Arne
  Mit Zitat antworten Zitat