Передать аргументы с помощью ShellExecute в Powershell с администратором

Я пытаюсь запустить PowerShell от имени администратора, используя ShellExecute в программе Qt, но аргументы, похоже, не передаются.

QString ruleName = QCoreApplication::applicationName();
QString exePath = QCoreApplication::applicationFilePath();

// Define the embedded PowerShell scripts as strings
const QString checkFirewallScript = QString(
"param([string]$ruleName,[string]$exePath)"
"a powershell script of 70 lines"
).arg(ruleName, exePath);

// Construct the PowerShell command with the script
QString command = QString("powershell.exe -Command \"%1\"").arg(checkFirewallScript);

// Convert the command to a wide string
LPCWSTR commandC = (const wchar_t*) command.utf16();

// Use ShellExecute to run the command as administrator
HINSTANCE exitCode = ShellExecute(NULL, L"runas", L"powershell.exe", commandC, NULL, SW_SHOWNORMAL);

Мой код выхода всегда 42, хотя я читал, что выше 32, это просто номер экземпляра. Я получаю предупреждение в поле ошибки Qt «QString::arg: 2 аргумента(ов) отсутствует», и оно выдает сценарий. У меня нет знаков процента, и сценарий работает в PowerShell сам по себе (когда я добавляю два «отсутствующих» аргумента непосредственно в сценарий). Это также работало без проблем, когда я использовал Qt Process, но я хочу, чтобы UAC вызывался, поэтому я использую ShellExecute (который, согласно заголовкам, является ShellExecuteW).

command повторяет имя исполняемого файла. Это неправильно. Для правильного сообщения об ошибках вместо этого вызовите ShellExecuteExW. Ни вызов API (ни CreateProcessW, если уж на то пошло) не сообщит о результатах вновь созданного процесса.
IInspectable 18.06.2024 23:16

Правильный способ использования Qt — это API QProcess. Вам следует удалить теги Qt из вашего вопроса или переформулировать его с помощью QProcess.

Jens 19.06.2024 13:47

@Йенс Йенс Ты прав. Я пытаюсь подключить UAC, поэтому на самом деле я не использую Qt, кроме некоторых начальных строк.

ConductedForce 19.06.2024 13:54
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
// Get the application file path and name
QString ruleName = QCoreApplication::applicationName();
QString exePath = QCoreApplication::applicationFilePath();

// Define the embedded PowerShell scripts as strings
const QString checkFirewallScript = R"(param(
        [Parameter(Mandatory=$true)][string]$ruleName,
        [Parameter(Mandatory=$true)][string]$exePath
    )
    $rules = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue |
    ...
)";

// Construct the command to run PowerShell with the script
QString command = QString("-ExecutionPolicy Bypass -F \"%1\" -ruleName \"%2\" -exePath \"%3\"")
                      .arg(tempScriptPath)
                      .arg(ruleName)
                      .arg(exePath);

// Convert the command to a wide string
std::wstring commandW = command.toStdWString();

// Initialize the SHELLEXECUTEINFO structure
SHELLEXECUTEINFOW sei = {0};
sei.cbSize = sizeof(SHELLEXECUTEINFOW);
sei.fMask = SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS;
sei.hwnd = NULL;
sei.lpVerb = L"runas";
sei.lpFile = L"powershell.exe";
sei.lpParameters = commandW.c_str();;
sei.lpDirectory = NULL;
sei.nShow = SW_SHOWNORMAL;
sei.hInstApp = NULL;

//run
if (!ShellExecuteExW(&sei)) { ...

WaitForSingleObject(sei.hProcess, 10000);    // 10 seconds
DWORD exitCode;
GetExitCodeProcess(sei.hProcess, &exitCode);
CloseHandle(sei.hProcess);

if (exitCode == 18000) {

Это потребовало некоторых усилий, пришлось отказаться от запуска всего сценария в качестве аргумента, потому что я продолжал сталкиваться со слишком большим количеством проблем. Это позволяет мне запускать powershell в отдельном окне, а также запрашивать разрешения администратора для выполнения некоторого обслуживания брандмауэра. Спасибо
IInspectable для рекомендации ShellExecuteExW, я могу использовать собственные коды ошибок в сценарии. Я не публиковал весь скрипт + функцию, но здесь представлены хорошие стороны.

пришлось ждать 2 дня

ConductedForce 21.06.2024 07:45

Другие вопросы по теме