| 18204 | } |
| 18205 | |
| 18206 | bool QKeyMapper_Worker::runCommand(const QString &cmdLine, |
| 18207 | bool runWait, |
| 18208 | const QString &workDir, |
| 18209 | int showCmd, |
| 18210 | const QString &verb) |
| 18211 | { |
| 18212 | #ifdef DEBUG_LOGOUT_ON |
| 18213 | qDebug().nospace().noquote() |
| 18214 | << "[runCommand] cmdLine=\"" << cmdLine |
| 18215 | << "\", runWait=" << runWait |
| 18216 | << ", workDir=\"" << workDir |
| 18217 | << "\", verb=" << verb |
| 18218 | << ", showCmd=" << showCmdToString(showCmd); |
| 18219 | #endif |
| 18220 | |
| 18221 | // Prepare STARTUPINFO for CreateProcess |
| 18222 | STARTUPINFOW si = { sizeof(si) }; |
| 18223 | si.dwFlags = STARTF_USESHOWWINDOW; |
| 18224 | si.wShowWindow = static_cast<WORD>(showCmd); |
| 18225 | |
| 18226 | PROCESS_INFORMATION pi = {}; |
| 18227 | std::wstring cmd = cmdLine.toStdWString(); // Persist command line |
| 18228 | std::wstring wdir = workDir.isEmpty() ? L"" : workDir.toStdWString(); |
| 18229 | |
| 18230 | // If we have a system verb, skip CreateProcess and go directly to ShellExecute |
| 18231 | // This matches AutoHotkey's behavior where system verbs bypass CreateProcess |
| 18232 | if (!verb.isEmpty()) { |
| 18233 | #ifdef DEBUG_LOGOUT_ON |
| 18234 | qDebug() << "[runCommand] System verb detected, skipping CreateProcess ->" << verb; |
| 18235 | #endif |
| 18236 | } else { |
| 18237 | // Try CreateProcessW first (direct executable launch) - only when no system verb |
| 18238 | if (CreateProcessW( |
| 18239 | nullptr, // Application name |
| 18240 | cmd.data(), // Command line (must be writable) |
| 18241 | nullptr, nullptr, // Security attributes |
| 18242 | FALSE, // No handle inheritance |
| 18243 | 0, // Creation flags |
| 18244 | nullptr, // Environment |
| 18245 | wdir.empty() ? nullptr : wdir.c_str(), // Working directory |
| 18246 | &si, &pi)) |
| 18247 | { |
| 18248 | #ifdef DEBUG_LOGOUT_ON |
| 18249 | qDebug() << "[runCommand] CreateProcess succeeded"; |
| 18250 | #endif |
| 18251 | if (runWait) { |
| 18252 | WaitForSingleObject(pi.hProcess, INFINITE); |
| 18253 | } |
| 18254 | CloseHandle(pi.hProcess); |
| 18255 | CloseHandle(pi.hThread); |
| 18256 | return true; |
| 18257 | } |
| 18258 | #ifdef DEBUG_LOGOUT_ON |
| 18259 | else { |
| 18260 | qDebug() << "[runCommand] CreateProcess failed, trying ShellExecute"; |
| 18261 | } |
| 18262 | #endif |
| 18263 | } |
nothing calls this directly
no test coverage detected