Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Delphi procedure to run an external command line program and capture and display the output.
procedure RunProcessAndCaptureOutput(const CmdLine: string; Memo: TMemo; HideLinesCount: Integer = 0);
var
SecAttr: TSecurityAttributes;
PipeR, PipeW: THandle;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
Buffer: packed array[0..4096-1] of AnsiChar;
Count: Cardinal;
S, Leftover: AnsiString;
i, P: Cardinal;
C: AnsiChar;
begin
SecAttr.nLength:=SizeOf(SecAttr);
SecAttr.lpSecurityDescriptor:=nil;
SecAttr.bInheritHandle:=True;
if not CreatePipe(PipeR, PipeW, @SecAttr, 0) then
raise Exception.Create('CreatePipe: '+SysErrorMessage(GetLastError));
SetHandleInformation(PipeR, HANDLE_FLAG_INHERIT, 0);
FillChar(StartupInfo, SizeOf(StartupInfo), 0);
StartupInfo.cb:=SizeOf(StartupInfo);
StartupInfo.dwFlags:=STARTF_USESTDHANDLES;
StartupInfo.hStdOutput:=PipeW;
StartupInfo.hStdError:=PipeW;
FillChar(ProcessInfo, SizeOf(ProcessInfo), 0);
if not CreateProcess(nil, PChar(CmdLine), nil, nil, True, CREATE_NO_WINDOW, nil, nil, StartupInfo, ProcessInfo) then
raise Exception.Create('CreateProcess: '+SysErrorMessage(GetLastError));
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
CloseHandle(PipeW);
Leftover:='';
while ReadFile(PipeR, Buffer[0], SizeOf(Buffer)-1, Count, nil) and (Count > 0) do
begin
Buffer[Count]:=#0;
i:=0;
P:=0;
while i < Count do
begin
C:=Buffer[i];
if C in [#10, #13] then
begin
if HideLinesCount > 0 then
Dec(HideLinesCount)
else
begin
Buffer[i]:=#0;
S:=Leftover+AnsiString(PAnsiChar(@Buffer[P]));
OemToCharBuffA(@S[1], @S[1], Length(S));
Memo.Lines.Add(string(S));
end;
Leftover:='';
case C of
#10: if Buffer[i+1] = #13 then Inc(i);
#13: if Buffer[i+1] = #10 then Inc(i);
end;
P:=i+1;
end;
Inc(i);
end;
Leftover:=AnsiString(PAnsiChar(@Buffer[P]));
Application.ProcessMessages;
end;
if (Leftover <> '') and (HideLinesCount <= 0) then
begin
OemToCharBuffA(@Leftover[1], @Leftover[1], Length(Leftover));
Memo.Lines.Add(string(Leftover));
end;
CloseHandle(PipeR);
end;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.