diff --git a/src/libs/utils/terminalprocess.cpp b/src/libs/utils/terminalprocess.cpp index 30d02fed72e..1f74153e9f6 100644 --- a/src/libs/utils/terminalprocess.cpp +++ b/src/libs/utils/terminalprocess.cpp @@ -243,48 +243,6 @@ static QString createWinCommandline(const QString &program, const QString &args) return programName; } -bool TerminalProcess::startTerminalEmulator(const QString &workingDir, const Environment &env) -{ -#ifdef Q_OS_WIN - 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 - - QString totalEnvironment = env.toStringList().join(QChar(QChar::Null)) + QChar(QChar::Null); - LPVOID envPtr = (env != Environment::systemEnvironment()) - ? (WCHAR *)(totalEnvironment.utf16()) : nullptr; - - bool success = CreateProcessW(0, (WCHAR *)cmdLine.utf16(), - 0, 0, FALSE, CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT, - envPtr, workingDir.isEmpty() ? 0 : (WCHAR *)workingDir.utf16(), - &si, &pinfo); - - if (success) { - CloseHandle(pinfo.hThread); - CloseHandle(pinfo.hProcess); - } - - return success; -#else - const TerminalCommand term = TerminalCommand::terminalEmulator(); - QProcess process; - process.setProgram(term.command); - process.setArguments(ProcessArgs::splitArgs(term.openArgs)); - process.setProcessEnvironment(env.toProcessEnvironment()); - process.setWorkingDirectory(workingDir); - - return process.startDetached(); -#endif -} - void TerminalProcess::setAbortOnMetaChars(bool abort) { d->m_abortOnMetaChars = abort; diff --git a/src/libs/utils/terminalprocess_p.h b/src/libs/utils/terminalprocess_p.h index 612981f22c0..006b3c3d8a0 100644 --- a/src/libs/utils/terminalprocess_p.h +++ b/src/libs/utils/terminalprocess_p.h @@ -74,8 +74,6 @@ public: void interruptProcess(); // only debugger terminal, only non-windows qint64 applicationMainThreadID() const; // only debugger terminal, only windows (-1 otherwise) - static bool startTerminalEmulator(const QString &workingDir, const Environment &env); - signals: void started(); void finished(int exitCode, QProcess::ExitStatus status); diff --git a/src/plugins/coreplugin/fileutils.cpp b/src/plugins/coreplugin/fileutils.cpp index 3f54d49d278..538e2120f0c 100644 --- a/src/plugins/coreplugin/fileutils.cpp +++ b/src/plugins/coreplugin/fileutils.cpp @@ -34,10 +34,10 @@ #include #include #include -#include #include #include #include +#include #include #include @@ -51,6 +51,15 @@ #include #include +#ifdef Q_OS_WIN + +#include +#include +#include + +#endif + + using namespace Utils; namespace Core { @@ -128,6 +137,59 @@ void FileUtils::showInFileSystemView(const FilePath &path) navWidget->syncWithFilePath(path); } +static QString quoteWinCommand(const QString &program) +{ + const QChar doubleQuote = QLatin1Char('"'); + + // add the program as the first arg ... it works better + QString programName = program; + programName.replace(QLatin1Char('/'), QLatin1Char('\\')); + if (!programName.startsWith(doubleQuote) && !programName.endsWith(doubleQuote) + && programName.contains(QLatin1Char(' '))) { + programName.prepend(doubleQuote); + programName.append(doubleQuote); + } + return programName; +} + +static void startTerminalEmulator(const QString &workingDir, const Environment &env) +{ +#ifdef Q_OS_WIN + STARTUPINFO si; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + + PROCESS_INFORMATION pinfo; + ZeroMemory(&pinfo, sizeof(pinfo)); + + const QString cmdLine = quoteWinCommand(QString::fromLocal8Bit(qgetenv("COMSPEC"))); + // cmdLine is assumed to be detached - + // https://blogs.msdn.microsoft.com/oldnewthing/20090601-00/?p=18083 + + const QString totalEnvironment = env.toStringList().join(QChar(QChar::Null)) + QChar(QChar::Null); + LPVOID envPtr = (env != Environment::systemEnvironment()) + ? (WCHAR *)(totalEnvironment.utf16()) : nullptr; + + const bool success = CreateProcessW(0, (WCHAR *)cmdLine.utf16(), + 0, 0, FALSE, CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT, + envPtr, workingDir.isEmpty() ? 0 : (WCHAR *)workingDir.utf16(), + &si, &pinfo); + + if (success) { + CloseHandle(pinfo.hThread); + CloseHandle(pinfo.hProcess); + } +#else + const TerminalCommand term = TerminalCommand::terminalEmulator(); + QProcess process; + process.setProgram(term.command); + process.setArguments(ProcessArgs::splitArgs(term.openArgs)); + process.setProcessEnvironment(env.toProcessEnvironment()); + process.setWorkingDirectory(workingDir); + process.startDetached(); +#endif +} + void FileUtils::openTerminal(const FilePath &path) { openTerminal(path, Environment::systemEnvironment()); @@ -136,10 +198,10 @@ void FileUtils::openTerminal(const FilePath &path) void FileUtils::openTerminal(const FilePath &path, const Environment &env) { const QFileInfo fileInfo = path.toFileInfo(); - const QString pwd = QDir::toNativeSeparators(fileInfo.isDir() ? - fileInfo.absoluteFilePath() : - fileInfo.absolutePath()); - ConsoleProcess::startTerminalEmulator(pwd, env); + const QString workingDir = QDir::toNativeSeparators(fileInfo.isDir() ? + fileInfo.absoluteFilePath() : + fileInfo.absolutePath()); + startTerminalEmulator(workingDir, env); } QString FileUtils::msgFindInDirectory()