ReadFile works fine inside VS C++ IDE but fails stand-alone

134 views Asked by At

Currently I have two apps, one with a GUI (written using MFC) and the other as a standard executable. The GUI app (parent) triggers the standard app (child) using CreateProcessW call and parent receives messages from its child via an anonymous pipe. The message receiving process works fine when I run the parent inside the VS IDE. However, if I run the parent standalone, parent does not receive any messages from its child (i.e. parent get hang in ReadFile call, waiting for messages).

Any thoughts on this?

Note: After creation of anonymous pipe, all read operations happens inside a separate thread and it does not block either UI or main thread. Some code related to child process creation and used parameters are given below.

// 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
                              );
1

There are 1 answers

0
Suranjith On

managed to solve this issue. Previously I was updating parent's output and error handlers to newly created handlers in order to retrieve them when creating a child process. However, this doesn't seem to be working. When I modify the code to pass the pipe handlers via a pointer or a reference then things started to work fine.

However this does not explain the reason for running inside IDE and failing it in stand-alone mode.

//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);