Die einfachste Variante (ohne zwischen Ergbnisse) ist folgende:
Delphi-Quellcode:
function ExecAndCaptureConsoleApp(CommandLine: String; OutputWindow: hWnd): Integer;
const
BufSize = $4000;
var
StartupInfo:TStartupInfo;
ProcessInfo:TProcessInformation;
WriteHandle, ReadHandle: THandle;
ReadBuf: array[0..BufSize] of Char;
BytesRead: DWord;
begin
FillChar(StartupInfo,SizeOf(StartupInfo), 0);
FillChar(ReadBuf, SizeOf(ReadBuf), 0);
CreatePipe(ReadHandle, WriteHandle, nil, BufSize);
with StartupInfo do begin
cb:= SizeOf(StartupInfo);
dwFlags:= STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
hStdOutput:= WriteHandle;
hStdError:= WriteHandle;
wShowWindow:= SW_HIDE;
end;
if not CreateProcess(nil, PChar(CommandLine), nil, nil, false, DETACHED_PROCESS or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo) then begin
Result:= -1
end else
begin
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
ReadFile( ReadHandle, ReadBuf, BufSize, BytesRead, nil);
SetWindowText(OutputWindow, ReadBuf);
GetExitCodeProcess(ProcessInfo.hProcess, DWord(Result));
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread)
end;
CloseHandle(WriteHandle)
end;
Die Ausgabe erfolgt über SetWindowText und dafür kann man z.B.: ein Memo.Handle angeben.
Besser ist es natürlich z.B. eine TStringlist zu befüllen und diese zurückzugeben oder auch bei längeren Aufrufen über
[Delphi}
Win32Check(GetExitCodeProcess(FProcessInfo.hProces s, FExitCode)); // liefert STILL_ACTIVE bis der Process endet
[/Delphi]
in einer Schleife abzufragen, ob der Prozess noch läuft und gegebenenfalls Rückgaben sofort anzuzeigen.