2013-04-19 2 views
2

Я пытаюсь следовать 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 тоже не помогли.

+0

Код вашей трубы не заполнен. См. MSDN для более полного примера: [Как вызвать консольные процессы с перенаправленными стандартными дескрипторами] (http://support.microsoft.com/kb/190351) –

+0

@RemyLebeau На самом деле единственное изменение, которое необходимо внести в код в вопросе работа заключается в наследовании ручек при вызове 'CreateProcess'. –

ответ

3

Самый очевидный недостаток, который я вижу, заключается в том, что вы установили bInheritHandles в False, когда вы позвоните CreateProcess. Вы должны пройти True, и, когда вы это сделаете, ваш код работает должным образом. Выходной сигнал от nap.exe достоверно считывается в Buf.

+0

Спасибо ... Я не знаю, как я это пропустил. –

Смежные вопросы