I have a console application that I launch from a GUI applicaiton. The console application takes parameters for filenames to parse and process. Currently I am able to capture its output and display it in the GUI application but I would like to be able to send commands to it so as to control or even halt its execution.
How can I send a command or string or anything to the console application, preferably using the pipes that I opened in order to read its output?
const
CReadBuffer = 2400;
var
saSecurity: TSecurityAttributes;
hRead: THandle;
hWrite: THandle;
suiStartup: TStartupInfo;
piProcess: TProcessInformation;
pBuffer: array[0..CReadBuffer] of AnsiChar;
dRead: DWord;
dRunning: DWord;
dWritten: DWord;
Command: String;
BytesLeft: Integer;
BytesAvail: Integer;
begin
saSecurity.nLength := SizeOf(TSecurityAttributes);
saSecurity.bInheritHandle := True;
saSecurity.lpSecurityDescriptor := nil;
if CreatePipe(hRead, hWrite, @saSecurity, 0) then
begin
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;
Command := 'messageparser.exe c:messagefile.msg';
UniqueString(Command);
if CreateProcess(nil, PChar(Command), @saSecurity,
@saSecurity, True, NORMAL_PRIORITY_CLASS, nil, nil, suiStartup, piProcess) then
begin
repeat
dRunning := WaitForSingleObject(piProcess.hProcess, 100);
Application.ProcessMessages;
repeat
dRead := 0;
if not PeekNamedPipe(hread, @pbuffer, CReadBuffer, @dRead, @BytesAvail, @BytesLeft) then
RaiseLastOSError;
if dRead <> 0 then
begin
ReadFile(hRead, pBuffer[0], CReadBuffer, dRead, nil);
pBuffer[dRead] := #0;
OemToCharA(pBuffer, pBuffer);
// do something with the data
// if a condition is present then do the following:
// WriteFile(hWrite, some_command, size_of_buffer, DWritten, nil);
end;
until (dRead < CReadBuffer);
until (dRunning <> WAIT_TIMEOUT);
CloseHandle(piProcess.hProcess);
CloseHandle(piProcess.hThread);
end;
CloseHandle(hRead);
CloseHandle(hWrite);
end;
Then on the console side, there is a thread waiting for the input. Here is the execute method:
while not Terminated do
begin
ReadLn(Command);
// process command
Sleep(10);
end;
This is new to me so if there are tips on how do it right, I welcome them :). However whenever I send a Command, it comes over as whatever I read in the pBuffer from the ReadPipe and not what the command is.
Hope this helps.
--
Found a solution based on the tip by Nat.
Bi-directional communication between gui and console
See Question&Answers more detail:
os