Jak wysłać polecenie do aplikacji konsoli z aplikacji GUI
Mam aplikację konsoli, którą uruchamiam z aplikacji GUI. Aplikacja konsoli pobiera parametry dla nazw plików do analizy i przetwarzania. Obecnie jestem w stanie przechwycić jego wyjście i wyświetlić go w aplikacji GUI, ale chciałbym móc wysyłać do niego polecenia, aby kontrolować lub nawet zatrzymać jego wykonanie.
Jak mogę wysłać polecenie lub ciąg znaków lub cokolwiek do aplikacji konsoli, najlepiej używając rur, które otworzyłem, aby odczytać jej wyjście?
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;
Następnie po stronie konsoli jest wątek czekający na wejście. Oto metoda wykonania:
while not Terminated do
begin
ReadLn(Command);
// process command
Sleep(10);
end;
To dla mnie nowość, więc jeśli są wskazówki, jak to zrobić, witam ich :). Jednak za każdym razem, gdy wysyłam polecenie, przychodzi ono jako cokolwiek, co czytam w pBufferze z ReadPipe, a nie to, co jest poleceniem.
Mam nadzieję że to pomoże.
-
Znaleziono rozwiązanie oparte na wskazówkach Nat.