2014-10-10 135 views
0

在下面的代码中,我使用“commandLine”参数来创建另一个进程,但是这个子进程可能没有写入管道,所以readfile函数会阻塞。
如何让它在没有数据的情况下返回?从管道中读取文件被阻塞

if (CreateProcess(nil, PChar('cmd.exe /C ' + CommandLine), @saSecurity, @saSecurity, True, NORMAL_PRIORITY_CLASS, nil, nil, suiStartup, piProcess)) 
    then 
    sOutputString := ''; 
    begin 

    repeat 

     dRunning := WaitForSingleObject(piProcess.hProcess, 100); 
     Application.ProcessMessages(); 

    until (dRunning <> WAIT_TIMEOUT); 

    CloseHandle(piProcess.hProcess); 
    CloseHandle(piProcess.hThread); 

    repeat 
     dRead := 0; 

     ReadFile(hRead, pBuffer[0], CReadBuffer, dRead, nil); 
     // But it is blocked...... 

    until (dRead < CReadBuffer); 

    end; 
+0

阅读这是错误的做法反正之前的数据。即使其他进程*写入管道,程序仍可能卡住。管道有一个固定大小的缓冲区。如果远程进程*填充了该缓冲区,那么*将阻塞*,直到管道的另一端(即进程)从管道读取并为更多数据腾出空间。因此,您需要确保您的进程不会被阻塞,等待远程进程终止。您需要在数据到达时读取数据*以保持两个进程的响应。 – 2014-10-10 13:23:50

+0

是的,你是非常正确的。首先,第二个重复条款包含在第一个重复条款中。但是因为我不知道如何处理块问题,所以我打算等待子进程终止。这真的是一个错误,我知道为什么现在,谢谢! – dltigles 2014-10-10 13:42:13

+1

什么管道?你的ReadFile应该立即返回0,你不会创建任何管道。 – 2014-10-10 13:43:34

回答

1

您可以检查是否命名管道包含它

if PeekNamedPipe(hRead, nil, 0, nil, @dwBytesAvailable, nil) then 
begin 
    if dwBytesAvailable > 0 then 
    begin 
     ReadFile(...); 
    end; 
end; 
+0

非常感谢! – dltigles 2014-10-10 13:26:52

+0

也可以'WaitForSingleObject(hReadPipe)' – 2014-10-10 15:44:54