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.