Skip to content
Snippets Groups Projects
Commit bcefb62a authored by Daniel Molkentin's avatar Daniel Molkentin
Browse files

(un)install -> (un)register, add nogui mode for use in installer

The nogui mode is required for the installer, to keep the noise low.
Also, get rid of QApplication passing, as all methods we call
are static anyway, which made the compiler complain about
unreferenced formal parameters.

Revieved-by: Friedemann Kleint
parent ac5f165c
No related branches found
No related tags found
No related merge requests found
...@@ -68,10 +68,11 @@ static inline QString wCharToQString(const WCHAR *w) { return QString::fromUtf16 ...@@ -68,10 +68,11 @@ static inline QString wCharToQString(const WCHAR *w) { return QString::fromUtf16
#endif #endif
enum Mode { HelpMode, InstallMode, UninstallMode, PromptMode, ForceCreatorMode, ForceDefaultMode }; enum Mode { HelpMode, RegisterMode, UnregisterMode, PromptMode, ForceCreatorMode, ForceDefaultMode };
Mode optMode = PromptMode; Mode optMode = PromptMode;
bool optIsWow = false; bool optIsWow = false;
bool noguiMode = false;
unsigned long argProcessId = 0; unsigned long argProcessId = 0;
quint64 argWinCrashEvent = 0; quint64 argWinCrashEvent = 0;
...@@ -113,12 +114,14 @@ static bool parseArguments(const QStringList &args, QString *errorMessage) ...@@ -113,12 +114,14 @@ static bool parseArguments(const QStringList &args, QString *errorMessage)
optMode = ForceCreatorMode; optMode = ForceCreatorMode;
} else if (arg == QLatin1String("default")) { } else if (arg == QLatin1String("default")) {
optMode = ForceDefaultMode; optMode = ForceDefaultMode;
} else if (arg == QLatin1String("install")) { } else if (arg == QLatin1String("register")) {
optMode = InstallMode; optMode = RegisterMode;
} else if (arg == QLatin1String("uninstall")) { } else if (arg == QLatin1String("unregister")) {
optMode = UninstallMode; optMode = UnregisterMode;
} else if (arg == QLatin1String("wow")) { } else if (arg == QLatin1String("wow")) {
optIsWow = true; optIsWow = true;
} else if (arg == QLatin1String("nogui")) {
noguiMode = true;
} else { } else {
*errorMessage = QString::fromLatin1("Unexpected option: %1").arg(arg); *errorMessage = QString::fromLatin1("Unexpected option: %1").arg(arg);
return false; return false;
...@@ -141,8 +144,8 @@ static bool parseArguments(const QStringList &args, QString *errorMessage) ...@@ -141,8 +144,8 @@ static bool parseArguments(const QStringList &args, QString *errorMessage)
} }
switch (optMode) { switch (optMode) {
case HelpMode: case HelpMode:
case InstallMode: case RegisterMode:
case UninstallMode: case UnregisterMode:
break; break;
default: default:
if (argProcessId == 0) { if (argProcessId == 0) {
...@@ -166,13 +169,14 @@ static void usage(const QString &binary, const QString &message = QString()) ...@@ -166,13 +169,14 @@ static void usage(const QString &binary, const QString &message = QString())
str << "<b>" << message << "</b>"; str << "<b>" << message << "</b>";
} }
str << "<pre>" str << "<pre>"
<< "Usage: " << QFileInfo(binary).baseName() << "[-wow] [-help|-?|qtcreator|default|install|uninstall] &lt;process-id> &lt;event-id>\n" << "Usage: " << QFileInfo(binary).baseName() << "[-wow] [-help|-?|qtcreator|default|register|unregister] &lt;process-id> &lt;event-id>\n"
<< "Options: -help, -? Display this help\n" << "Options: -help, -? Display this help\n"
<< " -qtcreator Launch Qt Creator without prompting\n" << " -qtcreator Launch Qt Creator without prompting\n"
<< " -default Launch Default handler without prompting\n" << " -default Launch Default handler without prompting\n"
<< " -install Install itself (requires administrative privileges)\n" << " -register Register as post mortem debugger (requires administrative privileges)\n"
<< " -uninstall Uninstall itself (requires administrative privileges)\n" << " -unregister Unregister as post mortem debugger (requires administrative privileges)\n"
<< " -wow Indicates Wow32 call\n" << " -wow Indicates Wow32 call\n"
<< " -nogui Do not show error messages in popup windows\n"
<< "</pre>" << "</pre>"
<< "<p>To install, modify the registry key <i>HKEY_LOCAL_MACHINE\\" << wCharToQString(debuggerRegistryKeyC) << "<p>To install, modify the registry key <i>HKEY_LOCAL_MACHINE\\" << wCharToQString(debuggerRegistryKeyC)
<< "</i>:</p><ul>" << "</i>:</p><ul>"
...@@ -339,9 +343,9 @@ static QString getProcessBaseName(DWORD pid) ...@@ -339,9 +343,9 @@ static QString getProcessBaseName(DWORD pid)
// ------- main modes // ------- main modes
bool startCreatorAsDebugger(const QApplication &a, QString *errorMessage) bool startCreatorAsDebugger(QString *errorMessage)
{ {
const QString dir = a.applicationDirPath(); const QString dir = QApplication::applicationDirPath();
const QString binary = dir + QLatin1String("/qtcreator.exe"); const QString binary = dir + QLatin1String("/qtcreator.exe");
QStringList args; QStringList args;
args << QLatin1String("-debug") << QString::number(argProcessId) args << QLatin1String("-debug") << QString::number(argProcessId)
...@@ -359,7 +363,7 @@ bool startCreatorAsDebugger(const QApplication &a, QString *errorMessage) ...@@ -359,7 +363,7 @@ bool startCreatorAsDebugger(const QApplication &a, QString *errorMessage)
return true; return true;
} }
bool startDefaultDebugger(const QApplication & /*a*/, QString *errorMessage) bool startDefaultDebugger(QString *errorMessage)
{ {
// Read out default value // Read out default value
HKEY handle; HKEY handle;
...@@ -395,7 +399,7 @@ bool startDefaultDebugger(const QApplication & /*a*/, QString *errorMessage) ...@@ -395,7 +399,7 @@ bool startDefaultDebugger(const QApplication & /*a*/, QString *errorMessage)
return true; return true;
} }
bool chooseDebugger(const QApplication &a, QString *errorMessage) bool chooseDebugger(QString *errorMessage)
{ {
const QString msg = QString::fromLatin1("The application \"%1\" (process id %2) crashed. Would you like to debug it?").arg(getProcessBaseName(argProcessId)).arg(argProcessId); const QString msg = QString::fromLatin1("The application \"%1\" (process id %2) crashed. Would you like to debug it?").arg(getProcessBaseName(argProcessId)).arg(argProcessId);
QMessageBox msgBox(QMessageBox::Information, QLatin1String(titleC), msg, QMessageBox::Cancel); QMessageBox msgBox(QMessageBox::Information, QLatin1String(titleC), msg, QMessageBox::Cancel);
...@@ -404,30 +408,30 @@ bool chooseDebugger(const QApplication &a, QString *errorMessage) ...@@ -404,30 +408,30 @@ bool chooseDebugger(const QApplication &a, QString *errorMessage)
msgBox.exec(); msgBox.exec();
if (msgBox.clickedButton() == creatorButton) { if (msgBox.clickedButton() == creatorButton) {
// Just in case, default to standard // Just in case, default to standard
if (startCreatorAsDebugger(a, errorMessage)) if (startCreatorAsDebugger(errorMessage))
return true; return true;
return startDefaultDebugger(a, errorMessage); return startDefaultDebugger(errorMessage);
} }
if (msgBox.clickedButton() == defaultButton) if (msgBox.clickedButton() == defaultButton)
return startDefaultDebugger(a, errorMessage); return startDefaultDebugger(errorMessage);
return true; return true;
} }
// Installation helpers: Format the debugger call with placeholders for PID and event // Installation helpers: Format the debugger call with placeholders for PID and event
// '"[path]\qtcdebugger" [-wow] %ld %ld'. // '"[path]\qtcdebugger" [-wow] %ld %ld'.
static QString debuggerCall(const QApplication &a, const QString &additionalOption = QString()) static QString debuggerCall(const QString &additionalOption = QString())
{ {
QString rc; QString rc;
QTextStream str(&rc); QTextStream str(&rc);
str << '"' << QDir::toNativeSeparators(a.applicationFilePath()) << '"'; str << '"' << QDir::toNativeSeparators(QApplication::applicationFilePath()) << '"';
if (!additionalOption.isEmpty()) if (!additionalOption.isEmpty())
str << ' ' << additionalOption; str << ' ' << additionalOption;
str << " %ld %ld"; str << " %ld %ld";
return rc; return rc;
} }
// Installation helper: Register ourselves in a debugger registry key. // registration helper: Register ourselves in a debugger registry key.
// Make a copy of the old value as "Debugger.Default" and have the // Make a copy of the old value as "Debugger.Default" and have the
// "Debug" key point to us. // "Debug" key point to us.
...@@ -444,7 +448,7 @@ static bool registerDebuggerKey(const WCHAR *key, ...@@ -444,7 +448,7 @@ static bool registerDebuggerKey(const WCHAR *key,
if (!registryReadStringKey(handle, debuggerRegistryValueNameC, &oldDebugger, errorMessage)) if (!registryReadStringKey(handle, debuggerRegistryValueNameC, &oldDebugger, errorMessage))
break; break;
if (oldDebugger.contains(QLatin1String(applicationFileC), Qt::CaseInsensitive)) { if (oldDebugger.contains(QLatin1String(applicationFileC), Qt::CaseInsensitive)) {
*errorMessage = QLatin1String("The program is already installed."); *errorMessage = QLatin1String("The program is already registered as post mortem debugger.");
return false; return false;
} }
if (!registryWriteStringKey(handle, debuggerRegistryDefaultValueNameC, oldDebugger, errorMessage)) if (!registryWriteStringKey(handle, debuggerRegistryDefaultValueNameC, oldDebugger, errorMessage))
...@@ -460,18 +464,18 @@ static bool registerDebuggerKey(const WCHAR *key, ...@@ -460,18 +464,18 @@ static bool registerDebuggerKey(const WCHAR *key,
return success; return success;
} }
bool install(const QApplication &a, QString *errorMessage) bool install(QString *errorMessage)
{ {
if (!registerDebuggerKey(debuggerRegistryKeyC, debuggerCall(a), errorMessage)) if (!registerDebuggerKey(debuggerRegistryKeyC, debuggerCall(), errorMessage))
return false; return false;
#ifdef Q_OS_WIN64 #ifdef Q_OS_WIN64
if (!registerDebuggerKey(debuggerWow32RegistryKeyC, debuggerCall(a, QLatin1String("-wow")), errorMessage)) if (!registerDebuggerKey(debuggerWow32RegistryKeyC, debuggerCall(QLatin1String("-wow")), errorMessage))
return false; return false;
#endif #endif
return true; return true;
} }
// Uninstall helper: Restore the original debugger key // Unregister helper: Restore the original debugger key
static bool unregisterDebuggerKey(const WCHAR *key, QString *errorMessage) static bool unregisterDebuggerKey(const WCHAR *key, QString *errorMessage)
{ {
HKEY handle = 0; HKEY handle = 0;
...@@ -494,7 +498,7 @@ static bool unregisterDebuggerKey(const WCHAR *key, QString *errorMessage) ...@@ -494,7 +498,7 @@ static bool unregisterDebuggerKey(const WCHAR *key, QString *errorMessage)
} }
bool uninstall(const QApplication & /*a*/, QString *errorMessage) bool uninstall(QString *errorMessage)
{ {
if (!unregisterDebuggerKey(debuggerRegistryKeyC, errorMessage)) if (!unregisterDebuggerKey(debuggerRegistryKeyC, errorMessage))
return false; return false;
...@@ -509,11 +513,11 @@ bool uninstall(const QApplication & /*a*/, QString *errorMessage) ...@@ -509,11 +513,11 @@ bool uninstall(const QApplication & /*a*/, QString *errorMessage)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication a(argc, argv); QApplication a(argc, argv);
a.setApplicationName(QLatin1String(titleC)); QApplication::setApplicationName(QLatin1String(titleC));
a.setOrganizationName(QLatin1String(organizationC)); QApplication::setOrganizationName(QLatin1String(organizationC));
QString errorMessage; QString errorMessage;
if (!parseArguments(a.arguments(), &errorMessage)) { if (!parseArguments(QApplication::arguments(), &errorMessage)) {
qWarning("%s\n", qPrintable(errorMessage)); qWarning("%s\n", qPrintable(errorMessage));
usage(QCoreApplication::applicationFilePath(), errorMessage); usage(QCoreApplication::applicationFilePath(), errorMessage);
return -1; return -1;
...@@ -526,24 +530,26 @@ int main(int argc, char *argv[]) ...@@ -526,24 +530,26 @@ int main(int argc, char *argv[])
usage(QCoreApplication::applicationFilePath(), errorMessage); usage(QCoreApplication::applicationFilePath(), errorMessage);
break; break;
case ForceCreatorMode: case ForceCreatorMode:
ex = startCreatorAsDebugger(a, &errorMessage) ? 0 : -1; ex = startCreatorAsDebugger(&errorMessage) ? 0 : -1;
break; break;
case ForceDefaultMode: case ForceDefaultMode:
ex = startDefaultDebugger(a, &errorMessage) ? 0 : -1; ex = startDefaultDebugger(&errorMessage) ? 0 : -1;
break; break;
case PromptMode: case PromptMode:
ex = chooseDebugger(a, &errorMessage) ? 0 : -1; ex = chooseDebugger(&errorMessage) ? 0 : -1;
break; break;
case InstallMode: case RegisterMode:
ex = install(a, &errorMessage) ? 0 : -1; ex = install(&errorMessage) ? 0 : -1;
break; break;
case UninstallMode: case UnregisterMode:
ex = uninstall(a, &errorMessage) ? 0 : -1; ex = uninstall(&errorMessage) ? 0 : -1;
break; break;
} }
if (ex && !errorMessage.isEmpty()) { if (ex && !errorMessage.isEmpty()) {
qWarning("%s\n", qPrintable(errorMessage)); if (noguiMode)
QMessageBox::warning(0, QLatin1String(titleC), errorMessage, QMessageBox::Ok); qWarning("%s\n", qPrintable(errorMessage));
else
QMessageBox::warning(0, QLatin1String(titleC), errorMessage, QMessageBox::Ok);
} }
return ex; return ex;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment