Re: Redirect stdout, stder in a GUI
 
Vincent RICHOMME a 9crit :
Also tried this
CConsoleRedirector::CConsoleRedirector()
{
    // Creation des  events
   m_hEndThread = CreateEvent(0, TRUE, FALSE, 0);
   m_hWaitThread = CreateEvent(0, TRUE, FALSE, 0);
   m_hStdin  = ::GetStdHandle(STD_INPUT_HANDLE);
   m_hStdout = ::GetStdHandle(STD_OUTPUT_HANDLE);
   m_hStderr = ::GetStdHandle(STD_ERROR_HANDLE);
   m_hStdoutReadEnd	= NULL;
   m_hStdoutWriteEnd	= NULL;
}
CConsoleRedirector::~CConsoleRedirector()
{
    // declenche la fin du thread
   ::SetEvent(m_hEndThread);
   // attend que le thread soit termin9
   ::WaitForSingleObject(m_hWaitThread, INFINITE);
   // fermeture dans handles
   ::CloseHandle(m_hEndThread);
   ::CloseHandle(m_hWaitThread);
   ::SetStdHandle(STD_INPUT_HANDLE,m_hStdin);
   ::SetStdHandle(STD_OUTPUT_HANDLE,m_hStdout);
   ::SetStdHandle(STD_ERROR_HANDLE,m_hStderr);
}
UINT CConsoleRedirector::ThreadFunc(LPVOID pvParam)
{
    CConsoleRedirector *pThis = static_cast<CConsoleRedirector *>(pvParam);
    return pThis->ThreadFunc();
}
UINT CConsoleRedirector::ThreadFunc()
{
    BYTE	Buffer[256]				= {0};
    DWORD	dwBytesRead				= 0;
    DWORD	dwTotalBytesAvail		= 0;
    DWORD	dwBytesLeftThisMessage	= 0;
    int		iRet = 0;
    while(true)
    {
        // attente evenement de fin du thread. -> lobjet doit :tre signal9 
        // WaitForSingleObject  renvoie WAIT_OBJECT_0 si lobjet est signal9.
        if(::WaitForSingleObject(m_hEndThread, 0) == WAIT_OBJECT_0)	
        {
            // signale l'objet event d'attente et sort.
            ::SetEvent(m_hWaitThread);
            return 0;
        }
        // Code de traitement.
        iRet = ReadFile(m_hStdoutWriteEnd, Buffer, 256 , &dwBytesRead, NULL);
        if( ( iRet) && (dwBytesRead) ){
            AfxMessageBox( _T("HELLO WORLD") );
        }
    }
    return 0;
}
void CConsoleRedirector::Init()
{
    SECURITY_ATTRIBUTES		saAttr;
    BOOL					bInheritHandles = FALSE;
    int						iRet = 0;
    //--- Redirect stdout & stderr-----//
    AllocConsole();
   /* Create the stdout anonymous pipe */
   if ( !mkAnonPipe( &m_hStdoutReadEnd, FALSE, &m_hStdoutWriteEnd, TRUE) ) {
      return;
   }
   // redirect stdout
   SetStdHandle(STD_OUTPUT_HANDLE, m_hStdoutReadEnd);
   // cin, cout, cerr point to console as well
   std::ios::sync_with_stdio();
    if (iRet == 0)
        AfxBeginThread(ThreadFunc,this,THREAD_PRIORITY_NORMAL,0,0,NULL);
    cout << "qsdqsdqdsd" << endl;
}
Hi,
I am still trying to redirect stdout and stderr in my MFC app (GUI)
So I do this :
BOOL CDemo1App::InitInstance()
{
    // Redirect COnsole IO (stdin, stdout, stderr)
    m_consRedir.Init();
}
with consRedir a CConsoleRedirector object defined like this :
CConsoleRedirector::CConsoleRedirector()
{
    // Creation des  events
  m_hEndThread = CreateEvent(0, TRUE, FALSE, 0);
  m_hWaitThread = CreateEvent(0, TRUE, FALSE, 0);
  m_hReadPipe    = NULL;
  m_hWritePipe    = NULL;
}
CConsoleRedirector::~CConsoleRedirector()
{
  ::SetEvent(m_hEndThread);
  ::WaitForSingleObject(m_hWaitThread, INFINITE);
  // Close handles
  ::CloseHandle(m_hEndThread);
  ::CloseHandle(m_hWaitThread);
  dup2(_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT), 1);
}
UINT CConsoleRedirector::ThreadFunc(LPVOID pvParam)
{
    CConsoleRedirector *pThis = static_cast<CConsoleRedirector *>(pvParam);
    return pThis->ThreadFunc();
    
    
}
UINT CConsoleRedirector::ThreadFunc()
{
    BYTE    Buffer[256]                = {0};
    DWORD    dwBytesRead                = 0;
    DWORD    dwTotalBytesAvail        = 0;
    DWORD    dwBytesLeftThisMessage    = 0;
    while(true)
    {
     if(::WaitForSingleObject(m_hEndThread, 0) == WAIT_OBJECT_0)   
    {
         ::SetEvent(m_hWaitThread);
         return 0;
    }
       
        // Code de traitement.
    if( (ReadFile(m_hReadPipe, Buffer, 256 , &dwBytesRead, NULL) )   && 
(dwBytesRead) ){
            AfxMessageBox( _T("HELLO WORLD") );
        }
    }
    return 0;
}
void CConsoleRedirector::Init()
{
    SECURITY_ATTRIBUTES        saAttr;
    BOOL                    bInheritHandles = FALSE;
    int                        iRet = 0;
    
    //--- Create  Pipe-----//   
    ZeroMemory(&saAttr,sizeof(SECURITY_ATTRIBUTES) );
    saAttr.nLength    = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;
    //--- Redirect stdout & stderr-----//   
    if ( CreatePipe(&m_hReadPipe, &m_hWritePipe, &saAttr, 0) )
    {
       iRet = dup2(_open_osfhandle((long)m_hReadPipe,  _O_TEXT), 2);
    }
    CloseHandle(m_hWritePipe);
    // cin, cout, cerr point to console as well
    std::ios::sync_with_stdio();
    
    // Start Watching thread
    if (iRet == 0)
    AfxBeginThread(ThreadFunc,this,THREAD_PRIORITY_NORMAL,0,0,NULL);
}
But it doesn't seem to work.
Any Idea ? I could also use AllocConsole but I don't want to see the 
console.