目前我有两个应用程序,一个带有GUI(使用MFC编写),另一个带有标准可执行文件。 GUI应用程序(父级)使用CreateProcessW
调用触发标准应用程序(子级),父级通过匿名管道从其子级接收消息。当我在VS IDE中运行父级时,消息接收过程正常。但是,如果我运行父独立,父节点不会收到来自其子节点的任何消息(即父节点在ReadFile调用中挂起,等待消息)。
对此有何想法?
注意:在创建匿名管道之后,所有读取操作都在单独的线程内发生,并且它不会阻止UI或主线程。下面给出了与子进程创建和使用参数相关的一些代码。
// pipe creation code
SECURITY_ATTRIBUTES saAttr;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the child process's STDOUT.
if ( ! CreatePipe(&m_hChildStd_OUT_Rd, &m_hChildStd_OUT_Wr, &saAttr, 0) )
{
m_logger->log( __FILE__, __LINE__, EventSeverity::WARNING, "Pipe cannot be created, will not receive meassages from child processes" );
}
// Ensure the read handle to the pipe for STDOUT is not inherited.
if ( ! SetHandleInformation(m_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
{
m_logger->log( __FILE__, __LINE__, EventSeverity::WARNING, "Could not make the read handler of the anonymous pipe not-inheritable" );
}
SetStdHandle(STD_OUTPUT_HANDLE, m_hChildStd_OUT_Wr);
SetStdHandle(STD_ERROR_HANDLE, m_hChildStd_OUT_Wr);
//Child process creation code
m_startupInfo.lpDesktop = NULL;
m_startupInfo.lpReserved = NULL;
m_startupInfo.lpReserved2 = NULL;
m_startupInfo.lpTitle = NULL;
m_startupInfo.hStdError = GetStdHandle(STD_OUTPUT_HANDLE);
m_startupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
m_startupInfo.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
m_startupInfo.cb = sizeof( m_startupInfo );
// launch the executable
m_isExecuting = CreateProcessW( app.exe, // lpApplicationName
m_pwszParam, // lpCommandLine
0, // lpProcessAttributes
0, // lpThreadAttributes
TRUE, // bInheritHandles
CREATE_NEW_PROCESS_GROUP, // dwCreationFlags
NULL, // lpEnvironment
curent working directory // lpCurrentDirectory
&m_startupInfo, // lpStartupInfo
&m_processInfo // lpProcessInformation
);
答案 0 :(得分:0)
设法解决了这个问题。以前我将父输出和错误处理程序更新为新创建的处理程序,以便在创建子进程时检索它们。但是,这似乎不起作用。当我修改代码以通过指针或引用传递管道处理程序时,事情开始正常工作。
但是,这并不能解释在IDE中运行并在独立模式下失败的原因。
//set the handler
SetStdHandle(STD_OUTPUT_HANDLE, m_hChildStd_OUT_Wr);
SetStdHandle(STD_ERROR_HANDLE, m_hChildStd_OUT_Wr);
//get the handler
m_startupInfo.hStdError = GetStdHandle(STD_OUTPUT_HANDLE);
m_startupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);