Hallo Forum,
bitte nicht hauen, wenn ich das falsche Unterforum erwischt haben sollte, denn wie ihr seht, schreibe ich zum ersten Mal hier in der
DP . Ich fand dies das passendste Unterforum.
Ich weiß, dass DOS-Ausgaben usw. schon mehrfach behandelt wurden, aber ich habe ein spezielleres Problem.
Ich habe eine Klasse TLaunch, die versch. Eigenschaften und
VCL-Objekte (z.B. einen Button) beinhaltet. Beim Klick auf diesen Button wird der in den Eigenschaften des Objekts gespeicherte Befehl ausgeführt, und zwar unter Verwendung dieser Methode:
Delphi-Quellcode:
procedure TMainForm.LaunchClick(Sender: TObject);
const BufSize = 1024;
var
// Ausführung mit Capture
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..BufSize] of Char;
BytesRead: Cardinal;
begin
obj:= (Sender as TLaunch);
LogForm.LogMemo.Clear;
LogForm.CloseBtn.Enabled:= False;
LogForm.MyShowModal;
with SA do
begin
nLength:= SizeOf(SA);
bInheritHandle:= True;
lpSecurityDescriptor:= nil;
end;
try
CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0);
Application.ProcessMessages;
with SI do
begin
FillChar(SI, SizeOf(SI), 0);
cb:= SizeOf(SI);
dwFlags:= STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow:= SW_HIDE;
hStdInput:= GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
hStdOutput:= StdOutPipeWrite;
hStdError:= StdOutPipeWrite;
end;
WasOK:= CreateProcess(nil, PChar(obj.ExecFile + ' ' + obj.ExecParams),
nil, nil, True, 0, nil,
PChar(obj.ExecWorkDir),
SI, PI);
CloseHandle(StdOutPipeWrite);
if WasOK then
try
Application.ProcessMessages;
repeat
Application.ProcessMessages;
WasOK:= ReadFile(StdOutPipeRead, Buffer, Pred(BufSize), BytesRead, nil);
if BytesRead > 0 then
begin
Buffer[BytesRead]:= #0;
OemToChar(Buffer, Buffer);
LogForm.LogMemo.Text:= LogForm.LogMemo.Text + String(Buffer);
end;
Sleep(50);
until not WasOK or (BytesRead = 0);
WaitForSingleObject(PI.hProcess, INFINITE);
finally
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
finally
CloseHandle(StdOutPipeRead);
//CloseHandle(StdOutPipeWrite);
end;
LogForm.CloseBtn.Enabled:= True;
LogForm.CloseBtn.SetFocus;
end;
Die Ausgabe wird auch wunderbar im Memo angezeigt, und das auch schön "in Echtzeit", also nicht erst nach Ende des Programms. Nun zum Problem: Programme, die Ausgaben in derselben Zeile erzeugen (chkdsk, wget, freshclam), generieren dann derartigen Output (gekürzt):
Code:
Der Typ des Dateisystems ist FAT32.
Datenträger SYSTEM erstellt 29.08.2006 00:34
Datenträgernummer: 44F3-8B85
Dateien und Ordner werden überprüft...
0 Prozent durchgeführt.
3 Prozent durchgeführt..
4 Prozent durchgeführt...
5 Prozent durchgeführt....
6 Prozent durchgeführt.....
7 Prozent durchgeführt......
8 Prozent durchgeführt.
9 Prozent durchgeführt..
10 Prozent durchgeführt...
11 Prozent durchgeführt....
12 Prozent durchgeführt.....
13 Prozent durchgeführt......
14 Prozent durchgeführt.
15 Prozent durchgeführt..
16 Prozent durchgeführt...
17 Prozent durchgeführt....
18 Prozent durchgeführt.....
19 Prozent durchgeführt......
Allerdings stehen die Prozentangaben alle in einer Zeile, die dann vom Memo irgendwann umgebrochen werden (bei maximaler Stringlänge oder so).
Hat jemand eine Idee, wie ich wirklich nur die Zeilen bekomme, die man auch sieht, wenn man die Befehle in der CMD ausführen würde?
Danke im Voraus für Hilfe
MfG Dalai