Решил написать программу чтобы управлять cmd.exe не привлекая внимания санитаров.
Мне надо: запустить процесс, получить вывод.
Потом сделать ввод, затем считать вывод. и так постоянно.
Работа с Pipe из разряда научной фантастики.
С помощью CreateProcess запускаю cmd.exe с параметрами "cmd /c dir".
После запуска процесса в предыдущей функции на 30 строке я создаю с помощью
CreateThread поток ReadThreadProc
Здесь я считываю данные из PipeOutputRead и вывожу их в Memo.
<hr>
Время от времени я записываю данные в hPipeInputWrite:
Иногда принудительно завершаю поток/процесс cmd.exe
Проблема в том, что при работе этого кода постоянно возникают ошибки:
Access Violation, External exception C0000008 и т.д.
Работа с Pipe из разряда научной фантастики.
Иногда работает иногда нет. Что я делаю не правильно?
Прочитал стотью с майкософт ком. ясности не привнесло
https://learn.microsoft.com/ru-ru/w...hild-process-with-redirected-input-and-output
Мне надо: запустить процесс, получить вывод.
Потом сделать ввод, затем считать вывод. и так постоянно.
Работа с Pipe из разряда научной фантастики.
С помощью CreateProcess запускаю cmd.exe с параметрами "cmd /c dir".
Код:
procedure StartExe(s: string); //Стартуем! В дорогу нам пора
var
WaitThreadId: Cardinal;
StartupInfo: TStartupInfo;
SecurityAttributes: TSecurityAttributes;
ProcessInformation: TProcessInformation;
begin
Form1.Memo2.Lines.Add('Process started.');
ZeroMemory(@SecurityAttributes, SizeOf(SecurityAttributes));
SecurityAttributes.nLength := SizeOf(TSecurityAttributes);
SecurityAttributes.lpSecurityDescriptor := nil;
SecurityAttributes.bInheritHandle := True;
CreatePipe(hPipeInputRead, hPipeInputWrite, @SecurityAttributes, 0);
//SetHandleInformation(hPipeInputRead, HANDLE_FLAG_INHERIT, 0);
CreatePipe(hPipeOutputRead, hPipeOutputWrite, @SecurityAttributes,
0);
//SetHandleInformation(hPipeOutputRead, HANDLE_FLAG_INHERIT, 0);
ZeroMemory(@StartupInfo, SizeOf(TStartupInfo));
ZeroMemory(@ProcessInformation, SizeOf(TProcessInformation));
StartupInfo.cb := SizeOf(TStartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
StartupInfo.wShowWindow := SW_HIDE;
StartupInfo.hStdInput := hPipeInputRead;
StartupInfo.hStdOutput := hPipeOutputWrite;
StartupInfo.hStdError := hPipeOutputWrite;
if CreateProcess(nil, PChar(s), nil, nil, True, CREATE_NEW_CONSOLE,
nil, nil, StartupInfo, ProcessInformation) then
begin
hProcess := ProcessInformation.hProcess;
hThread := CreateThread(nil, 0, @ReadThreadProc, nil, 0,
ThreadId);
end;
end;
CreateThread поток ReadThreadProc
Код:
procedure ReadThreadProc;
var
BytesCount: Cardinal;
buf: array [0..4096] of Char;
begin
Terminated := false;
while not Terminated do
begin
if hPipeOutputRead <> INVALID_HANDLE_VALUE then
begin
ZeroMemory(@buf, SizeOf(buf));
if ReadFile(hPipeOutputRead, buf, Length(buf), BytesCount, nil)
then
begin
if BytesCount <> 0 then
begin
//Вроде ошибка не здесь
OemToAnsiBuff(buf, buf, BytesCount);
Form1.Memo2.Text := Form1.Memo2.Text + Copy(buf, 1,
BytesCount);
end;
end;
end;
end;
end;
<hr>
Время от времени я записываю данные в hPipeInputWrite:
Код:
procedure InputText(s: string);
var
BytesCount: Cardinal;
buf: array [0..4096] of Char;
begin
//Проверяем размер вводимой строки:
if Length(s) < 4090 then
begin
ZeroMemory(@buf, SizeOf(buf));
StrPCopy(buf, s + #13#10); //
WriteFile(hPipeInputWrite, buf, Length(s) + 2, BytesCount, nil);
end;
end;
Код:
procedure StopThread(); //Эта часть кода с глюками и часто вылетает
begin
Terminated := true;
if ThreadId <> INVALID_HANDLE_VALUE then
begin
WaitForSingleObject(ThreadId, INFINITE);
end;
if hThread <> INVALID_HANDLE_VALUE then CloseHandle(hThread);
if hProcess <> INVALID_HANDLE_VALUE then
begin
TerminateProcess(hProcess, 255);
WaitForSingleObject(hProcess, INFINITE);
if hProcess <> INVALID_HANDLE_VALUE then CloseHandle(hProcess);
end;
if hPipeInputWrite <> INVALID_HANDLE_VALUE then CloseHandle
(hPipeInputWrite);
if hPipeInputRead <> INVALID_HANDLE_VALUE then CloseHandle
(hPipeInputRead);
if hPipeOutputWrite <> INVALID_HANDLE_VALUE then CloseHandle
(hPipeOutputWrite);
if hPipeOutputRead <> INVALID_HANDLE_VALUE then CloseHandle
(hPipeOutputRead);
end;
Access Violation, External exception C0000008 и т.д.
Работа с Pipe из разряда научной фантастики.
Иногда работает иногда нет. Что я делаю не правильно?
Прочитал стотью с майкософт ком. ясности не привнесло
https://learn.microsoft.com/ru-ru/w...hild-process-with-redirected-input-and-output
Последнее редактирование: