62 WCHAR browserExecutable[MAX_PATH] = {};
63 const wchar_t operation[] = L"open";
64 DWORD browserExecutableSize = MAX_PATH;
65 if (FAILED(AssocQueryString(0, ASSOCSTR_EXECUTABLE, L"http", operation,
66 browserExecutable, &browserExecutableSize))) {
69 QString browser = QString::fromWCharArray(browserExecutable, browserExecutableSize - 1);
71 if (browser.contains(
"LaunchWinApp.exe"_L1, Qt::CaseInsensitive))
72 browser =
"msedge.exe"_L1;
73 const QString urlS = url.toString(QUrl::FullyEncoded);
78 reinterpret_cast<
const wchar_t *>(browser.utf16())
,
79 reinterpret_cast<
const wchar_t *>(urlS.utf16())
);
83 const auto result =
reinterpret_cast<quintptr>(thread.result());
84 qCDebug(lcQpaServices) << urlS << QString::fromWCharArray(browserExecutable) << result;
87 qCWarning(lcQpaServices,
"%s", qPrintable(msgShellExecuteFailed(url, result)));
95 const QString nativeFilePath = url.isLocalFile() && !url.hasFragment() && !url.hasQuery()
96 ? QDir::toNativeSeparators(url.toLocalFile())
97 : url.toString(QUrl::FullyEncoded);
103 reinterpret_cast<
const wchar_t *>(nativeFilePath.utf16())
,
108 const auto result =
reinterpret_cast<quintptr>(thread.result());
112 qCWarning(lcQpaServices,
"%s", qPrintable(msgShellExecuteFailed(url, result)));
123 enum { BufferSize =
sizeof(
wchar_t) * MAX_PATH };
125 const wchar_t mailUserKey[] = L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\mailto\\UserChoice";
128 QString keyName = QWinRegistryKey(HKEY_CURRENT_USER, mailUserKey)
129 .stringValue( L"Progid");
130 const auto mailto = keyName.isEmpty() ?
"mailto"_L1 : QLatin1StringView();
131 keyName += mailto +
"\\Shell\\Open\\Command"_L1;
132 qCDebug(lcQpaServices) <<
"keyName=" << keyName;
133 const QString command = QWinRegistryKey(HKEY_CLASSES_ROOT, keyName).stringValue(L"");
138 if (command.isEmpty() || command.contains(u",MailToProtocolHandler"))
140 wchar_t expandedCommand[MAX_PATH] = {0};
141 return ExpandEnvironmentStrings(
reinterpret_cast<
const wchar_t *>(command.utf16()),
142 expandedCommand, MAX_PATH)
143 ? QString::fromWCharArray(expandedCommand) : command;
148 QString command = mailCommand();
149 if (command.isEmpty()) {
150 qCWarning(lcQpaServices,
"Cannot launch '%ls': There is no mail program installed.", qUtf16Printable(url.toString()));
154 if (command.indexOf(
"%1"_L1) < 0) {
155 qWarning(lcQpaServices) <<
"The mail command lacks the '%1' parameter.";
159 const QChar doubleQuote = u'"';
160 if (!command.startsWith(doubleQuote)) {
161 const int exeIndex = command.indexOf(
".exe "_L1, 0, Qt::CaseInsensitive);
162 if (exeIndex != -1) {
163 command.insert(exeIndex + 4, doubleQuote);
164 command.prepend(doubleQuote);
169 command.replace(
"%1"_L1, url.toString(QUrl::FullyEncoded));
170 qCDebug(lcQpaServices) <<
"Launching" << command;
172 PROCESS_INFORMATION pi;
173 ZeroMemory(&pi,
sizeof(pi));
175 ZeroMemory(&si,
sizeof(si));
177 if (!CreateProcess(
nullptr,
reinterpret_cast<
wchar_t *>(
const_cast<ushort *>(command.utf16())),
178 nullptr,
nullptr, FALSE, 0,
nullptr,
nullptr, &si, &pi)) {
179 qErrnoWarning(
"Unable to launch '%ls'", qUtf16Printable(command));
182 CloseHandle(pi.hProcess);
183 CloseHandle(pi.hThread);
187bool QWindowsServices::openUrl(
const QUrl &url)
189 const QString scheme = url.scheme();
190 if (scheme == u"mailto" && launchMail(url))
192 return url.isLocalFile() && url.hasFragment()
193 ? openWebBrowser(url) : shellExecute(url);