| 3051 | } |
| 3052 | |
| 3053 | bool RunProcessAsAdmin(const QString &fullExecutablePath, const QStringList ¶ms, |
| 3054 | QWidget *parent, bool hidden, std::function<void()> finishedCallback) |
| 3055 | { |
| 3056 | #if defined(Q_OS_WIN32) |
| 3057 | |
| 3058 | std::wstring wideExe = QDir::toNativeSeparators(fullExecutablePath).toStdWString(); |
| 3059 | std::wstring wideParams; |
| 3060 | |
| 3061 | for(QString p : params) |
| 3062 | { |
| 3063 | wideParams += L"\""; |
| 3064 | wideParams += p.toStdWString(); |
| 3065 | wideParams += L"\" "; |
| 3066 | } |
| 3067 | |
| 3068 | SHELLEXECUTEINFOW info = {}; |
| 3069 | info.cbSize = sizeof(info); |
| 3070 | info.fMask = SEE_MASK_NOCLOSEPROCESS; |
| 3071 | info.lpVerb = L"runas"; |
| 3072 | info.lpFile = wideExe.c_str(); |
| 3073 | info.lpParameters = wideParams.c_str(); |
| 3074 | info.nShow = hidden ? SW_HIDE : SW_SHOWNORMAL; |
| 3075 | |
| 3076 | ShellExecuteExW(&info); |
| 3077 | |
| 3078 | if((uintptr_t)info.hInstApp > 32 && info.hProcess != NULL) |
| 3079 | { |
| 3080 | if(finishedCallback) |
| 3081 | { |
| 3082 | HANDLE h = info.hProcess; |
| 3083 | |
| 3084 | // do the wait on another thread |
| 3085 | LambdaThread *thread = new LambdaThread([h, parent, finishedCallback]() { |
| 3086 | WaitForSingleObject(h, 30000); |
| 3087 | CloseHandle(h); |
| 3088 | GUIInvoke::call(parent, finishedCallback); |
| 3089 | }); |
| 3090 | thread->selfDelete(true); |
| 3091 | thread->start(); |
| 3092 | } |
| 3093 | else |
| 3094 | { |
| 3095 | CloseHandle(info.hProcess); |
| 3096 | } |
| 3097 | |
| 3098 | return true; |
| 3099 | } |
| 3100 | |
| 3101 | return false; |
| 3102 | |
| 3103 | #else |
| 3104 | // try to find a way to run the application elevated. |
| 3105 | const QString graphicalSudo[] = { |
| 3106 | lit("kdesudo"), |
| 3107 | lit("gksudo"), |
| 3108 | lit("beesu"), |
| 3109 | }; |
| 3110 |
no test coverage detected