Я пытаюсь следовать this msdn article.Чтение из порожденного процесса зависает оба процесса
Я создал очень простое консольное приложение.
Writeln('Take a nap.');
Sleep(1000);
Writeln('Done.');
Я использую следующий код для запуска консольного приложения и (попробуйте) прочитать его вывод. И консольное приложение, и основное приложение зависают.
procedure TForm1.Button1Click(Sender: TObject);
const
PATH: WideString = 'c:\tmp\nap.exe';
var
ProcInfo: TProcessInformation;
StartInfo: TStartupInfo;
WorkingDir: WideString;
StdOutRead, StdOutWrite: THandle;
Attr: SECURITY_ATTRIBUTES;
N: Cardinal;
Buf: Array [0.. 5000] of Byte;
begin
FillChar(Attr, SizeOf(SECURITY_ATTRIBUTES), 0);
Attr.nLength := SizeOf(SECURITY_ATTRIBUTES);
Attr.bInheritHandle := True;
Attr.lpSecurityDescriptor := nil;
if not (CreatePipe(StdOutRead, StdOutWrite, @Attr, 0)) then
RaiseLastOSError;
FillChar(StartInfo, SizeOf(TStartupInfo), 0);
StartInfo.cb := SizeOf(TStartupInfo);
StartInfo.dwFlags := STARTF_USESTDHANDLES;
StartInfo.hStdOutput := StdOutWrite;
// I've tried creating pipes for stdin and stderr to no avail
WorkingDir := ExtractFilePath(PATH);
if not CreateProcess(nil, PWideChar(PATH), nil, nil, false, 0, nil, PWideChar(WorkingDir), StartInfo, ProcInfo) then
RaiseLastOSError;
// this call hangs -- the console app hangs regardless
if not ReadFile(StdOutRead, Buf[0], Length(Buf), N, nil) then
RaiseLastOSError;
end;
Любые предложения ... к сожалению, this article тоже не помогли.
Код вашей трубы не заполнен. См. MSDN для более полного примера: [Как вызвать консольные процессы с перенаправленными стандартными дескрипторами] (http://support.microsoft.com/kb/190351) –
@RemyLebeau На самом деле единственное изменение, которое необходимо внести в код в вопросе работа заключается в наследовании ручек при вызове 'CreateProcess'. –