diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index d78164a11c9..2f3ca871d5e 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -477,8 +477,7 @@ QCoreApplicationPrivate::~QCoreApplicationPrivate() #endif #if defined(Q_OS_WIN) delete [] origArgv; - if (consoleAllocated) - FreeConsole(); + cleanupDebuggingConsole(); #endif QCoreApplicationPrivate::clearApplicationFilePath(); } @@ -576,49 +575,6 @@ QString qAppName() return QCoreApplication::instance()->d_func()->appName(); } -#ifdef Q_OS_WINDOWS -static bool hasValidStdOutHandle() -{ - const HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); - return h != NULL && h != INVALID_HANDLE_VALUE; -} -#endif - -void QCoreApplicationPrivate::initConsole() -{ -#ifdef Q_OS_WINDOWS - if (hasValidStdOutHandle()) - return; - const QString env = qEnvironmentVariable("QT_WIN_DEBUG_CONSOLE"); - if (env.isEmpty()) - return; - if (env.compare(u"new"_s, Qt::CaseInsensitive) == 0) { - if (AllocConsole() == FALSE) - return; - consoleAllocated = true; - } else if (env.compare(u"attach"_s, Qt::CaseInsensitive) == 0) { - // If the calling process is already attached to a console, - // the error code returned is ERROR_ACCESS_DENIED. - if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::GetLastError() != ERROR_ACCESS_DENIED) - return; - } else { - // Unknown input, don't make any decision for the user. - return; - } - // The std{in,out,err} handles are read-only, so we need to pass in dummies. - FILE *in = nullptr; - FILE *out = nullptr; - FILE *err = nullptr; - freopen_s(&in, "CONIN$", "r", stdin); - freopen_s(&out, "CONOUT$", "w", stdout); - freopen_s(&err, "CONOUT$", "w", stderr); - // However, things wouldn't work if the runtime did not preserve the pointers. - Q_ASSERT(in == stdin); - Q_ASSERT(out == stdout); - Q_ASSERT(err == stderr); -#endif -} - void QCoreApplicationPrivate::initLocale() { #if defined(QT_BOOTSTRAPPED) @@ -849,7 +805,9 @@ void Q_TRACE_INSTRUMENT(qtcore) QCoreApplicationPrivate::init() Q_Q(QCoreApplication); - initConsole(); +#ifdef Q_OS_WINDOWS + initDebuggingConsole(); +#endif initLocale(); diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index bfd65d2c9a0..0ad6eb6640e 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -78,7 +78,10 @@ public: static QString infoDictionaryStringProperty(const QString &propertyName); #endif - void initConsole(); +#ifdef Q_OS_WINDOWS + void initDebuggingConsole(); + void cleanupDebuggingConsole(); +#endif static void initLocale(); static bool checkInstance(const char *method); diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 3a69bec25be..963b0fe5cf6 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -841,4 +841,49 @@ void QCoreApplicationPrivate::removePostedTimerEvent(QObject *object, int timerI } #endif // QT_NO_QOBJECT +static bool hasValidStdOutHandle() +{ + const HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + return h != NULL && h != INVALID_HANDLE_VALUE; +} + +void QCoreApplicationPrivate::initDebuggingConsole() +{ + if (hasValidStdOutHandle()) + return; + const QString env = qEnvironmentVariable("QT_WIN_DEBUG_CONSOLE"); + if (env.isEmpty()) + return; + if (env.compare(u"new"_s, Qt::CaseInsensitive) == 0) { + if (AllocConsole() == FALSE) + return; + consoleAllocated = true; + } else if (env.compare(u"attach"_s, Qt::CaseInsensitive) == 0) { + // If the calling process is already attached to a console, + // the error code returned is ERROR_ACCESS_DENIED. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::GetLastError() != ERROR_ACCESS_DENIED) + return; + } else { + // Unknown input, don't make any decision for the user. + return; + } + // The std{in,out,err} handles are read-only, so we need to pass in dummies. + FILE *in = nullptr; + FILE *out = nullptr; + FILE *err = nullptr; + freopen_s(&in, "CONIN$", "r", stdin); + freopen_s(&out, "CONOUT$", "w", stdout); + freopen_s(&err, "CONOUT$", "w", stderr); + // However, things wouldn't work if the runtime did not preserve the pointers. + Q_ASSERT(in == stdin); + Q_ASSERT(out == stdout); + Q_ASSERT(err == stderr); +} + +void QCoreApplicationPrivate::cleanupDebuggingConsole() +{ + if (consoleAllocated) + FreeConsole(); +} + QT_END_NAMESPACE