63 WCHAR browserExecutable[MAX_PATH] = {};
64 const wchar_t operation[] = L"open";
65 DWORD browserExecutableSize = MAX_PATH;
66 if (FAILED(AssocQueryString(0, ASSOCSTR_EXECUTABLE, L"http", operation,
67 browserExecutable, &browserExecutableSize))) {
70 QString browser = QString::fromWCharArray(browserExecutable, browserExecutableSize - 1);
72 if (browser.contains(
"LaunchWinApp.exe"_L1, Qt::CaseInsensitive))
73 browser =
"msedge.exe"_L1;
74 const QString urlS = url.toString(QUrl::FullyEncoded);
79 reinterpret_cast<
const wchar_t *>(browser.utf16())
,
80 reinterpret_cast<
const wchar_t *>(urlS.utf16())
);
84 const auto result =
reinterpret_cast<quintptr>(thread.result());
85 qCDebug(lcQpaServices) << urlS << QString::fromWCharArray(browserExecutable) << result;
88 qCWarning(lcQpaServices,
"%s", qPrintable(msgShellExecuteFailed(url, result)));
96 const QString nativeFilePath = url.isLocalFile() && !url.hasFragment() && !url.hasQuery()
97 ? QDir::toNativeSeparators(url.toLocalFile())
98 : url.toString(QUrl::FullyEncoded);
104 reinterpret_cast<
const wchar_t *>(nativeFilePath.utf16())
,
109 const auto result =
reinterpret_cast<quintptr>(thread.result());
113 qCWarning(lcQpaServices,
"%s", qPrintable(msgShellExecuteFailed(url, result)));
124 enum { BufferSize =
sizeof(
wchar_t) * MAX_PATH };
126 const wchar_t mailUserKey[] = L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\mailto\\UserChoice";
129 QString keyName = QWinRegistryKey(HKEY_CURRENT_USER, mailUserKey)
130 .stringValue( L"Progid");
131 const auto mailto = keyName.isEmpty() ?
"mailto"_L1 : QLatin1StringView();
132 keyName += mailto +
"\\Shell\\Open\\Command"_L1;
133 qCDebug(lcQpaServices) <<
"keyName=" << keyName;
134 const QString command = QWinRegistryKey(HKEY_CLASSES_ROOT, keyName).stringValue(L"");
139 if (command.isEmpty() || command.contains(u",MailToProtocolHandler"))
141 wchar_t expandedCommand[MAX_PATH] = {0};
142 return ExpandEnvironmentStrings(
reinterpret_cast<
const wchar_t *>(command.utf16()),
143 expandedCommand, MAX_PATH)
144 ? QString::fromWCharArray(expandedCommand) : command;
149 QString command = mailCommand();
150 if (command.isEmpty()) {
151 qCWarning(lcQpaServices,
"Cannot launch '%ls': There is no mail program installed.", qUtf16Printable(url.toString()));
155 if (command.indexOf(
"%1"_L1) < 0) {
156 qWarning(lcQpaServices) <<
"The mail command lacks the '%1' parameter.";
160 const QChar doubleQuote = u'"';
161 if (!command.startsWith(doubleQuote)) {
162 const int exeIndex = command.indexOf(
".exe "_L1, 0, Qt::CaseInsensitive);
163 if (exeIndex != -1) {
164 command.insert(exeIndex + 4, doubleQuote);
165 command.prepend(doubleQuote);
170 command.replace(
"%1"_L1, url.toString(QUrl::FullyEncoded));
171 qCDebug(lcQpaServices) <<
"Launching" << command;
173 PROCESS_INFORMATION pi;
174 ZeroMemory(&pi,
sizeof(pi));
176 ZeroMemory(&si,
sizeof(si));
178 if (!CreateProcess(
nullptr,
reinterpret_cast<
wchar_t *>(
const_cast<ushort *>(command.utf16())),
179 nullptr,
nullptr, FALSE, 0,
nullptr,
nullptr, &si, &pi)) {
180 qErrnoWarning(
"Unable to launch '%ls'", qUtf16Printable(command));
183 CloseHandle(pi.hProcess);
184 CloseHandle(pi.hThread);
188bool QWindowsServices::openUrl(
const QUrl &url)
190 const QString scheme = url.scheme();
191 if (scheme == u"mailto" && launchMail(url))
193 return url.isLocalFile() && url.hasFragment()
194 ? openWebBrowser(url) : shellExecute(url);