我想读一个控制台程序输出。问题是ReadFile使我的线程死锁。即使过程存在仍然相同。我听说你必须关闭Write Pipe但是这样做时它什么都不读。
这是我的代码:
var
saSec : TSecurityAttributes;
hRead, hWrite : THandle;
SI : TStartupInfo;
PI : TProcessInformation;
Running,dwRead : DWORD;
buf : array [0..1024] of AnsiChar;
data : AnsiString;
begin
saSec.nLength := sizeof(TSecurityAttributes);
saSec.bInheritHandle := false;
saSec.lpSecurityDescriptor := nil;
if CreatePipe(hRead, hWrite, @saSec, 0) then
begin
FillChar(SI, Sizeof(TStartupInfo), #0);
FillChar(PI, Sizeof(TProcessInformation), #0);
SI.hStdInput := hRead;
SI.hStdOutput := hWrite;
SI.hStdError := hWrite;
SI.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
SI.wShowWindow := SW_HIDE;
if CreateProcess(nil, PChar('openvpn' + cert), @saSec, @saSec, False, NORMAL_PRIORITY_CLASS, nil, nil, SI, PI) then
begin
data := '';
repeat
Running := WaitForSingleObject(PI.hProcess, 100);
repeat
FillChar(buf, sizeof(buf), #0);
ReadFile(hRead, buf, sizeof(buf), dwRead, nil);
data := data + buf;
if Pos('sequence completed', data) >0 then
begin
status := 1;
Synchronize(Sync);
end;
until dwRead < sizeof(buf);
until Running <> WAIT_TIMEOUT ;
status := 0;
Synchronize(Sync);
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
end;
答案 0 :(得分:0)
除非您使用重叠I / O,否则ReadFile
将阻塞,直到从正在读取的句柄中获取数据,或者直到句柄上出现某些错误情况。
你正在等待从管道中读取什么都没有写入。您在创建句柄时禁用了继承,因此您创建的进程将不会接收它们。分配到saSec.bInheritHandle
时允许继承,至少在调用CreatePipe
之前。 (如果您不希望后续进程可以继承新进程和线程句柄,则可以更改它以准备CreateProcess
。)还要注意CreateProcess
的第五个参数,它控制相同的的事情。
Raymond Chen几年前发表了article expanding on the topic of inheriting handles。