File indexing completed on 2024-04-28 15:29:48

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2004-2008 Jarosław Staniek <staniek@kde.org>
0004     SPDX-FileCopyrightText: 2006 Ralf Habacker <ralf.habacker@freenet.de>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #include "ktoolinvocation.h"
0010 
0011 #include "kservice.h"
0012 
0013 #include <KLocalizedString>
0014 #include <KMessage>
0015 
0016 #include <QCoreApplication>
0017 #include <QHash>
0018 #include <QProcess>
0019 #include <QStandardPaths>
0020 #include <QUrl>
0021 #include <QUrlQuery>
0022 
0023 #include "windows.h"
0024 
0025 #include "shellapi.h" // Must be included after "windows.h"
0026 
0027 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 0)
0028 void KToolInvocation::invokeBrowser(const QString &url, const QByteArray &startup_id)
0029 {
0030 #ifndef _WIN32_WCE
0031     QString sOpen = QString::fromLatin1("open");
0032     ShellExecuteW(0, (LPCWSTR)sOpen.utf16(), (LPCWSTR)url.utf16(), 0, 0, SW_NORMAL);
0033 #else
0034     SHELLEXECUTEINFO cShellExecuteInfo = {0};
0035     cShellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO);
0036     cShellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
0037     cShellExecuteInfo.hwnd = NULL;
0038     cShellExecuteInfo.lpVerb = L"Open";
0039     cShellExecuteInfo.lpFile = (LPCWSTR)url.utf16();
0040     cShellExecuteInfo.nShow = SW_SHOWNORMAL;
0041     ShellExecuteEx(&cShellExecuteInfo);
0042 #endif
0043 }
0044 #endif
0045 
0046 void KToolInvocation::invokeMailer(const QString &_to,
0047                                    const QString &_cc,
0048                                    const QString &_bcc,
0049                                    const QString &subject,
0050                                    const QString &body,
0051                                    const QString & /*messageFile TODO*/,
0052                                    const QStringList &attachURLs,
0053                                    const QByteArray &startup_id)
0054 {
0055     QUrl url(QLatin1String("mailto:") + _to);
0056     QUrlQuery query;
0057     query.addQueryItem(QStringLiteral("subject"), subject);
0058     query.addQueryItem(QStringLiteral("cc"), _cc);
0059     query.addQueryItem(QStringLiteral("bcc"), _bcc);
0060     query.addQueryItem(QStringLiteral("body"), body);
0061     for (const QString &attachURL : attachURLs) {
0062         query.addQueryItem(QStringLiteral("attach"), attachURL);
0063     }
0064     url.setQuery(query);
0065 
0066 #ifndef _WIN32_WCE
0067     QString sOpen = QLatin1String("open");
0068     ShellExecuteW(0, (LPCWSTR)sOpen.utf16(), (LPCWSTR)url.url().utf16(), 0, 0, SW_NORMAL);
0069 #else
0070     SHELLEXECUTEINFO cShellExecuteInfo = {0};
0071     cShellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO);
0072     cShellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
0073     cShellExecuteInfo.hwnd = NULL;
0074     cShellExecuteInfo.lpVerb = L"Open";
0075     cShellExecuteInfo.lpFile = (LPCWSTR)url.url().utf16();
0076     cShellExecuteInfo.nShow = SW_SHOWNORMAL;
0077     ShellExecuteEx(&cShellExecuteInfo);
0078 #endif
0079 }
0080 
0081 void KToolInvocation::invokeTerminal(const QString &command, const QStringList &envs, const QString &workdir, const QByteArray &startup_id)
0082 {
0083     const QString windowsTerminal = QStringLiteral("wt.exe");
0084     const QString pwsh = QStringLiteral("pwsh.exe");
0085     const QString powershell = QStringLiteral("powershell.exe"); // Powershell is used as fallback
0086     const bool hasWindowsTerminal = !QStandardPaths::findExecutable(windowsTerminal).isEmpty();
0087     const bool hasPwsh = !QStandardPaths::findExecutable(pwsh).isEmpty();
0088 
0089     QProcess process;
0090     QStringList args;
0091     process.setWorkingDirectory(workdir);
0092 
0093     if (hasWindowsTerminal) {
0094         process.setProgram(windowsTerminal);
0095         if (!workdir.isEmpty()) {
0096             args << QStringLiteral("--startingDirectory") << workdir;
0097         }
0098         if (!command.isEmpty()) {
0099             // Command and NoExit flag will be added later
0100             args << (hasPwsh ? pwsh : powershell);
0101         }
0102     } else {
0103         process.setProgram(hasPwsh ? pwsh : powershell);
0104     }
0105     if (!command.isEmpty()) {
0106         args << QStringLiteral("-NoExit") << QStringLiteral("-Command") << command;
0107     }
0108     process.setArguments(args);
0109 
0110     if (!envs.isEmpty()) {
0111         QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
0112         for (const QString &envVar : envs) {
0113             const int splitIndex = envVar.indexOf(QLatin1Char('='));
0114             env.insert(envVar.left(splitIndex), envVar.mid(splitIndex + 1));
0115         }
0116         process.setProcessEnvironment(env);
0117     }
0118     process.setCreateProcessArgumentsModifier([](QProcess::CreateProcessArguments *args) {
0119         args->flags |= CREATE_NEW_CONSOLE;
0120         args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES;
0121     });
0122     process.startDetached();
0123 }
0124 
0125 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 79)
0126 void KToolInvocation::invokeTerminal(const QString &command, const QString &workdir, const QByteArray &startup_id)
0127 {
0128     invokeTerminal(command, QStringList(), workdir, startup_id);
0129 }
0130 #endif
0131 
0132 KServicePtr KToolInvocation::terminalApplication(const QString &command, const QString &workingDir)
0133 {
0134     return KServicePtr();
0135 }