[Qt-interest] stdout of MSWin GUI application run from console
Graeme Gill
graeme2 at argyllcms.com
Wed Apr 27 14:27:26 CEST 2011
Here's another update to this code, with a minor fix to make
it run properly on Vista and Win7.
As was hinted by a previous responder, it seems that Microsoft
changed cmd.exe in Vista and Win7 so that if you start a
GUI application from the command line, it doesn't wait for it to
exit (ie. it acts like "$ app.exe&" would with a Unix shell). This
behaviour can be avoided by either changing the cmd.exe shortcut
to start it with extensions off (ie. "cmd.exe /E:OFF"), or starting
the GUI application using one of the following ways:
start /wait app.exe
cmd /C app.exe
[This code seems to work as expected with 64 bit applications too.]
Graeme Gill.
-------------------------------------------------------------------
#include <QApplication>
#include <stdio.h>
#include "tdialog.hpp"
#ifdef Q_WS_WIN
#include <windows.h>
void winConsoleMsgHandler(QtMsgType t, const char* str) {
fprintf(stderr, "%s\n", str);
fflush(stderr);
}
#endif // Q_WS_WIN
int main(int argc, char *argv[]) {
#ifdef Q_WS_WIN
{
BOOL (WINAPI *AttachConsole)(DWORD dwProcessId);
AttachConsole = (BOOL (WINAPI*)(DWORD))
GetProcAddress(LoadLibraryA("kernel32.dll"), "AttachConsole");
if (AttachConsole != NULL && AttachConsole(((DWORD)-1))) {
if (_fileno(stdout) < 0)
freopen("CONOUT$","wb",stdout);
if (_fileno(stderr) < 0)
freopen("CONOUT$","wb",stderr);
if (_fileno(stdin) < 0)
freopen("CONIN$","rb",stdin);
// Fix C++
std::ios::sync_with_stdio();
// Fix messages
qInstallMsgHandler(winConsoleMsgHandler);
}
}
#endif // Q_WS_WIN
printf("This is stdout\n");
fprintf(stderr,"This is stderr\n");
qDebug("This is a qDebug message");
QApplication app(argc, argv);
TDialog *dialog = new TDialog;
dialog->show();
qDebug("This is another qDebug message");
return app.exec();
}
-------------------------------------------------------------------
*** src/corelib/kernel/qcoreapplication_win.cpp Thu Apr 14 11:17:48 2011
--- src/corelib/kernel/qcoreapplication_win.cpp Thu Apr 14 12:14:09 2011
*************** void qWinMain(HINSTANCE instance, HINSTA
*** 181,191 ****
qWarning("Qt: Internal error: qWinMain should be called only once");
return;
}
already_called = true;
- usingWinMain = true;
! // Install default debug handler
! qInstallMsgHandler(qWinMsgHandler);
// Create command line
argv = qWinCmdLine<char>(cmdParam, int(strlen(cmdParam)), argc);
--- 181,214 ----
qWarning("Qt: Internal error: qWinMain should be called only once");
return;
}
+
already_called = true;
! #ifdef Q_WS_WIN
! // Re-attach stdio if application was started from a console
! BOOL (WINAPI *pAttachConsole)(DWORD dwProcessId);
!
! pAttachConsole = (BOOL (WINAPI*)(DWORD))
! GetProcAddress(LoadLibraryA("kernel32.dll"), "AttachConsole");
!
! if (pAttachConsole != NULL && pAttachConsole(((DWORD)-1))) {
! if (_fileno(stdout) < 0)
! freopen("CONOUT$","wb",stdout);
! if (_fileno(stderr) < 0)
! freopen("CONOUT$","wb",stderr);
! if (_fileno(stdin) < 0)
! freopen("CONIN$","rb",stdin);
!
! // Fix C++
! std::ios::sync_with_stdio();
! } else
! #endif // Q_WS_WIN
! {
! usingWinMain = true; // Reset to qWinMsgHandler on qInstallMsgHandler(0)
!
! // Install default debug handler
! qInstallMsgHandler(qWinMsgHandler);
! }
// Create command line
argv = qWinCmdLine<char>(cmdParam, int(strlen(cmdParam)), argc);
More information about the Qt-interest-old
mailing list