This article implements running a console program in Delphi and displays the output of the console program in the Memo control.
I needed to manually compile J2ME programs at work. I started writing a batch program, but it felt very cumbersome to use, so I wanted to use Delphi to make an integrated compilation tool. However, the Java compilation tools are all console programs. How to capture the console program? Output and display it in Memo. After checking some information on the Internet and testing repeatedly, I found a way to implement it. I hope it will be helpful to everyone:
PRocedure TMainForm.RunDosInMemo(const DosApp: string; AMemo: TMemo);
const
{Set the size of ReadBuffer}
ReadBuffer = 2400;
var
Security: TSecurityAttributes;
ReadPipe, WritePipe: THandle;
start: TStartUpInfo;
ProcessInfo: TProcessInformation;
Buffer: PChar;
BytesRead: DWord;
Buf: string;
begin
with Security do
begin
nlength := SizeOf(TSecurityAttributes);
binherithandle := true;
lpsecuritydescriptor := nil;
end;
{Create a named pipe to capture the output of the console program}
if Createpipe(ReadPipe, WritePipe, @Security, 0) then
begin
Buffer := AllocMem(ReadBuffer + 1);
FillChar(Start, Sizeof(Start), #0)
{Set the startup attributes of the console program}
with start do
begin
cb := SizeOf(start);
start.lpReserved := nil;
lpDesktop := nil;
lpTitle := nil;
dwX := 0;
dwY := 0;
dwXSize := 0;
dwYSize := 0;
dwXCountChars := 0;
dwYCountChars := 0;
dwFillAttribute := 0;
cbReserved2 := 0;
lpReserved2 := nil;
hStdOutput := WritePipe; //Direct the output to the WritePipe we created
hStdInput := ReadPipe; //Direct input to the ReadPipe we created
hStdError := WritePipe;//Direct the error output to the WritePipe we created
dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
wShowWindow := SW_HIDE;//Set the window to hide
end;
try
{Create a child process and run the console program}
if CreateProcess(nil, PChar(DosApp), @Security, @Security, true,
NORMAL_PRIORITY_CLASS,
nil, nil, start, ProcessInfo) then
begin
{Wait for the process to finish running}
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
{Turn off the output...I didn't turn it off at first. As a result, if there is no output, the program will die. }
CloseHandle(WritePipe);
Buf := '';
{Read the output of the console program}
repeat
BytesRead := 0;
ReadFile(ReadPipe, Buffer[0], ReadBuffer, BytesRead, nil);
Buffer[BytesRead] := #0;
OemToAnsi(Buffer, Buffer);
Buf := Buf + string(Buffer);
until (BytesRead < ReadBuffer);
SendDebug(Buf);
{Split according to newlines and displayed in Memo}
while pos(#10, Buf) > 0 do
begin
AMemo.Lines.Add(Copy(Buf, 1, pos(#10, Buf) - 1));
Delete(Buf, 1, pos(#10, Buf));
end;
end;
finally
FreeMem(Buffer);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ReadPipe);
end;
end;
end;