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