From 453d191d0f351d4588fa5840fe94684c93088f25 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 4 Apr 2014 13:03:40 +0200 Subject: [PATCH] Prevent 'qmake -query' from bringing up modal message dialog on startup Temporarily set the ErrorMode so that no Windows error message box will show up in case qmake fails to run (e.g. because of missing .dll's). The error mode will automatically be inherited by child processes. This fixes an issue that actually became virulent by another bug fix ( cbb053068ccc6399dc7a39 ). Task-number: QTCREATORBUG-11962 Change-Id: I5baccf52baee46f3d45b69ea0a13d77e4e113fbd Reviewed-by: Friedemann Kleint Reviewed-by: Tobias Hunger --- src/libs/utils/winutils.cpp | 18 ++++++++++++++++++ src/libs/utils/winutils.h | 17 +++++++++++++++++ src/plugins/qtsupport/baseqtversion.cpp | 4 ++++ 3 files changed, 39 insertions(+) diff --git a/src/libs/utils/winutils.cpp b/src/libs/utils/winutils.cpp index 4e75d1eeeee..dfdb0cadd95 100644 --- a/src/libs/utils/winutils.cpp +++ b/src/libs/utils/winutils.cpp @@ -172,4 +172,22 @@ QTCREATOR_UTILS_EXPORT bool is64BitWindowsBinary(const QString &binaryIn) #endif } +WindowsCrashDialogBlocker::WindowsCrashDialogBlocker() +#ifdef Q_OS_WIN + : silenceErrorMode(SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS), + originalErrorMode(SetErrorMode(silenceErrorMode)) +#endif +{ +} + +WindowsCrashDialogBlocker::~WindowsCrashDialogBlocker() +{ +#ifdef Q_OS_WIN + unsigned int errorMode = SetErrorMode(originalErrorMode); + // someone else messed with the error mode in between? Better not touch ... + QTC_ASSERT(errorMode == silenceErrorMode, SetErrorMode(errorMode)); +#endif +} + + } // namespace Utils diff --git a/src/libs/utils/winutils.h b/src/libs/utils/winutils.h index 9b5358791a4..4fa59c67ab4 100644 --- a/src/libs/utils/winutils.h +++ b/src/libs/utils/winutils.h @@ -49,6 +49,23 @@ QTCREATOR_UTILS_EXPORT bool is64BitWindowsSystem(); // Check for a 64bit binary. QTCREATOR_UTILS_EXPORT bool is64BitWindowsBinary(const QString &binary); +// +// RAII class to temporarily prevent windows crash messages from popping up using the +// application-global (!) error mode. +// +// Useful primarily for QProcess launching, since the setting will be inherited. +// +class QTCREATOR_UTILS_EXPORT WindowsCrashDialogBlocker { +public: + WindowsCrashDialogBlocker(); + ~WindowsCrashDialogBlocker(); +#ifdef Q_OS_WIN +private: + const unsigned int silenceErrorMode; + const unsigned int originalErrorMode; +#endif // Q_OS_WIN +}; + } // namespace Utils #endif // WINUTILS_H diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 7a405484357..3ded2c6b24b 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -1206,6 +1207,9 @@ static QByteArray runQmakeQuery(const FileName &binary, const Environment &env, const int timeOutMS = 30000; // Might be slow on some machines. + // Prevent e.g. qmake 4.x on MinGW to show annoying errors about missing dll's. + WindowsCrashDialogBlocker crashDialogBlocker; + QProcess process; process.setEnvironment(env.toStringList()); process.start(binary.toString(), QStringList(QLatin1String("-query")), QIODevice::ReadOnly);