From ec50c146b3bff251d92e1bf106f23ac4e8a08e46 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 11 Jan 2017 13:55:31 +0100 Subject: [PATCH] fix "Open Command Prompt Here" on windows with qt 5.8 qt 5.8 made QProcess::startDetached()'s behavior consistent with start(), which means it won't open a console any more. however, qtc relied on this (unspecified) behavior. the correct solution is to add a static function startTerminalEmulator() to ConsoleProcess, which already has most of the necessary code anyway. Task-number: QTCREATORBUG-17439 Change-Id: Icf04666869ce6593555302a54c49331a29846a99 Reviewed-by: Tobias Hunger Reviewed-by: Robert Loehning --- src/libs/utils/consoleprocess.h | 2 ++ src/libs/utils/consoleprocess_unix.cpp | 6 ++++++ src/libs/utils/consoleprocess_win.cpp | 27 ++++++++++++++++++++++++++ src/plugins/coreplugin/fileutils.cpp | 21 ++------------------ 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/libs/utils/consoleprocess.h b/src/libs/utils/consoleprocess.h index 8a4e264de3a..6f081172583 100644 --- a/src/libs/utils/consoleprocess.h +++ b/src/libs/utils/consoleprocess.h @@ -91,6 +91,8 @@ public: static QString terminalEmulator(const QSettings *settings, bool nonEmpty = true); static void setTerminalEmulator(QSettings *settings, const QString &term); + static bool startTerminalEmulator(QSettings *settings, const QString &workingDir); + signals: void error(QProcess::ProcessError error); void processError(const QString &errorString); diff --git a/src/libs/utils/consoleprocess_unix.cpp b/src/libs/utils/consoleprocess_unix.cpp index 0b17543f93b..a4d0183d3e7 100644 --- a/src/libs/utils/consoleprocess_unix.cpp +++ b/src/libs/utils/consoleprocess_unix.cpp @@ -395,4 +395,10 @@ QStringList ConsoleProcess::availableTerminalEmulators() return result; } +bool ConsoleProcess::startTerminalEmulator(QSettings *settings, const QString &workingDir) +{ + const QString emu = QtcProcess::splitArgs(terminalEmulator(settings)).takeFirst(); + return QProcess::startDetached(emu, QStringList(), workingDir); +} + } // namespace Utils diff --git a/src/libs/utils/consoleprocess_win.cpp b/src/libs/utils/consoleprocess_win.cpp index 1301b93b637..dfdbbfdb71b 100644 --- a/src/libs/utils/consoleprocess_win.cpp +++ b/src/libs/utils/consoleprocess_win.cpp @@ -389,4 +389,31 @@ void ConsoleProcess::setSettings(QSettings *settings) // Not used on Windows } +bool ConsoleProcess::startTerminalEmulator(QSettings *, const QString &workingDir) +{ + STARTUPINFO si; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + + PROCESS_INFORMATION pinfo; + ZeroMemory(&pinfo, sizeof(pinfo)); + + QString cmdLine = createWinCommandline( + QString::fromLocal8Bit(qgetenv("COMSPEC")), QString()); + // cmdLine is assumed to be detached - + // https://blogs.msdn.microsoft.com/oldnewthing/20090601-00/?p=18083 + + bool success = CreateProcessW(0, (WCHAR *)cmdLine.utf16(), + 0, 0, FALSE, CREATE_NEW_CONSOLE, + 0, workingDir.isEmpty() ? 0 : (WCHAR *)workingDir.utf16(), + &si, &pinfo); + + if (success) { + CloseHandle(pinfo.hThread); + CloseHandle(pinfo.hProcess); + } + + return success; +} + } // namespace Utils diff --git a/src/plugins/coreplugin/fileutils.cpp b/src/plugins/coreplugin/fileutils.cpp index 17b525e9d86..1ec09f1a907 100644 --- a/src/plugins/coreplugin/fileutils.cpp +++ b/src/plugins/coreplugin/fileutils.cpp @@ -31,15 +31,14 @@ #include #include #include +#include #include -#include #include #include #include #include #include -#include #include #include @@ -110,27 +109,11 @@ void FileUtils::showInGraphicalShell(QWidget *parent, const QString &pathIn) void FileUtils::openTerminal(const QString &path) { - // Get terminal application - QString terminalEmulator; - QStringList args; - const OsType hostOs = HostOsInfo::hostOs(); - if (hostOs == OsTypeWindows) { - terminalEmulator = ConsoleProcess::defaultTerminalEmulator(); - } else if (hostOs == OsTypeMac) { - terminalEmulator = ICore::resourcePath() - + QLatin1String("/scripts/openTerminal.command"); - } else { - args = QtcProcess::splitArgs(ConsoleProcess::terminalEmulator(ICore::settings()), hostOs); - terminalEmulator = args.takeFirst(); - args.append(QString::fromLocal8Bit(qgetenv("SHELL"))); - } - - // Launch terminal with working directory set. const QFileInfo fileInfo(path); const QString pwd = QDir::toNativeSeparators(fileInfo.isDir() ? fileInfo.absoluteFilePath() : fileInfo.absolutePath()); - QProcess::startDetached(terminalEmulator, args, pwd); + ConsoleProcess::startTerminalEmulator(ICore::settings(), pwd); } QString FileUtils::msgFindInDirectory()