我正在使用CreateProcess触发一个进程,并且我想等待该进程完成,或者要将任何内容写到标准输出中,这是通过匿名管道进行的。下面的代码不起作用,因为WaitForMultipleObjects不断返回stdout管道,即使没有要读取的内容也是如此。有没有办法等待管道?我等不及要阅读,因为如果过程完成,我也需要继续。我也不能等到过程完成而不检查管道,因为管道可能会溢出。有任何想法吗?
if (::CreateProcess(
(!application_name.empty() ? application_name.c_str() : NULL), // Application/Executable name, if supplied.
lpCommandLine, // Arguments or Executable and Arguments
NULL, // Process Attributes
NULL, // Thread Attributes
TRUE, // Inherit handles
CREATE_NO_WINDOW, // Create flags
NULL, // Environment (Inherit)
current_directory.c_str(), // Working Directory
&m_startup_info, // Startup Info
&process_info // Process Info
))
{
HANDLE handles[2];
bool waiting = true;
handles[0] = process_info.hProcess;
handles[1] = m_read_stdout; // previously created with CreatePipe. One end handed to CreateProcess
// Must process stdout otherwise the process may block if it's output buffer fills!!
while (waiting)
{
DWORD r = ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
switch (r)
{
case WAIT_OBJECT_0+0:
waiting = false;
break;
case WAIT_OBJECT_0+1:
AppendSTDOUTFromProcess(output);
break;
default:
ATLASSERT(FALSE);
break;
}
}
}
管道不是可等待的对象,因此您不能在WaitFor...()
函数中使用它们。您可以:
用于WaitForSingleObject()
仅等待过程句柄,并为其指定超时,以便您的循环定期唤醒,然后可以调用PeekNamedPipe()
以检查管道中的数据。
在单独的线程中读取管道,在没有可用数据时让读取块,然后在管道关闭时终止线程。然后,您可以使用它WaitForMultipleObjects()
来等待进程和线程句柄。
根本不要等待流程句柄。只需从管道中读取循环,在没有可用数据时阻塞即可,直到在管道关闭时读取失败为止。这是Microsoft的示例使用的方法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句