Capturing output of External Programmes in Delphi?

  

I am a newbie to Delphi.

I am using the following code to capture console output in real-time and it is working.

unit Unit2;

interface
uses
Winapi.Windows,System.SysUtils, System.Types, System.UITypes,
System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Layouts, FMX.Gestures,
FMX.StdCtrls, FMX.Edit, FMX.Controls.Presentation, FMX.TabControl,
FMX.ComboEdit, FMX.Objects, FMX.Memo, FMX.ScrollBox, FMX.ListBox,
FMX.EditBox, FMX.NumberBox, FMX.SpinBox,System.IniFiles;

type
TArg<T>= reference to procedure(const Arg: T);
procedure Run(const ACommand, AParameters: String; CallBack:TArg<PAnsiChar>);

implementation
uses
unit1;

procedure Run(const ACommand, AParameters: String; CallBack:TArg<PAnsiChar>);
const
CReadBuffer = 2400;
var
saSecurity: TSecurityAttributes;
hRead: THandle;

hWrite: THandle;
suiStartup: TStartupInfo;
piProcess: TProcessInformation;
pBuffer: array[0..CReadBuffer] of AnsiChar;
dBuffer: array[0..CReadBuffer] of AnsiChar;
dRead: DWord;
dRunning: DWord;

dPresent: DWord;
begin
saSecurity.nLength := SizeOf(TSecurityAttributes);
saSecurity.bInheritHandle := True;
saSecurity.lpSecurityDescriptor := nil;
if CreatePipe(hRead, hWrite, @saSecurity, 0) then
try
FillChar(suiStartup, SizeOf(TStartupInfo), #0);
suiStartup.cb := SizeOf(TStartupInfo);
suiStartup.hStdInput := hRead;
suiStartup.hStdOutput := hWrite;
suiStartup.hStdError := hWrite;
suiStartup.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
suiStartup.wShowWindow := SW_HIDE;
if CreateProcess(nil, PChar(ACommand + ‘ ‘+AParameters) ,@saSecurity,@saSecurity, True, NORMAL_PRIORITY_CLASS, nil, nil, suiStartup,piProcess)
then
try
repeat
dRunning := WaitForSingleObject(piProcess.hProcess, 100);
PeekNamedPipe(hRead, nil,0,nil,@dPresent,nil);
if (dPresent > 0) then
repeat
dRead := 0;
ReadFile(hRead, pBuffer[0], CReadBuffer, dRead, nil);
pBuffer[dRead] := #0;

OemToCharA(pBuffer, dBuffer);
CallBack(dBuffer);
until (dRead < CReadBuffer);
Application.ProcessMessages();
until (dRunning <> WAIT_TIMEOUT);
Finally
CloseHandle(piProcess.hProcess);
CloseHandle(piProcess.hThread);
end;
Finally
CloseHandle(hRead);
CloseHandle(hWrite);
end;
end;
end.

and the following procedure to call it:

Run(ExtractFilePath(‘Java Version’,”,procedure(Const Line:PansiChar)
begin
Memo1.Lines.Add(String(Line));
end
)

The problem I am facing is after the above process is triggered, I can’t close the main form, I have to manually kill my app from Task Manager, and the background process is still running.

Also, the above code shows the progress texts of the external program in a TMemo, but it’s not updating, rather it writes the new progress string in each new line.

Comments are closed.