Подтвердить что ты не робот

Как запустить приложение, которое требует прав администратора от того, у кого их нет

Я застрял в этом несколько часов, пока, наконец, мне не удалось это сделать. Уже есть ссылки, которые указывали мне правильное направление:

Но я подумал, что простой обзор проблемы может помочь кому-то:).

4b9b3361

Ответ 1

Реальная проблема: (из Википедии: http://en.wikipedia.org/wiki/User_Account_Control)

Исполняемый файл, который помечен как "requireAdministrator" в своем манифесте, не может быть запущен из невыполненного процесса с помощью CreateProcess(). Вместо этого возвращается ERROR_ELEVATION_REQUIRED. Вместо этого следует использовать ShellExecute() или ShellExecuteEx().

(BTW, ERROR_ELEVATION_REQUIRED ошибка == 740)

Решение: (тот же сайт)

В собственном приложении Win32 тот же самый "runas" может быть добавлен к вызову ShellExecute() или ShellExecuteEx().

ShellExecute(hwnd, "runas", "C:\\Windows\\Notepad.exe", 0, 0, SW_SHOWNORMAL);

Это может быть полезно: (источник: http://mark.koli.ch/2009/12/uac-prompt-from-java-createprocess-error740-the-requested-operation-requires-elevation.html)

2 - Основной поток UAC

Хорошо, поэтому, прежде чем вы вникнете в него, я подумал, что было бы полезно объяснить основной поток приложения, поддерживающего UAC, и то, как все сочетается. Обычно ваше приложение работает как непривилегированный пользователь. Но иногда он должен быть Администратором (делать что угодно). Итак, вот основная идея, в псевдокоде:

int main (int argc, char **argv) {

  HRESULT operation = tryToDoSomethingPrivileged();

  if (operation == ACCESS_DENIED && !alreadyElevated) {

    // Spawn a copy of ourselves, via ShellExecuteEx().
    // The "runas" verb is important because that what
    // internally triggers Windows to open up a UAC prompt.
    HANDLE child = ShellExecuteEx(argc, argv, "runas");

    if (child) {
      // User accepted UAC prompt (gave permission).
      // The unprivileged parent should wait for
      // the privileged child to finish.
      WaitForSingleObject(child, INFINITE);
      CloseHandle(pid);
    }
    else {
      // User rejected UAC prompt.
      return FAILURE;
    }

    return SUCCESS;

  }  

  return SUCCESS;

}

Наконец, вот как я это сделал:

if(0 == CreateProcess(argv[2], params, NULL, NULL, false, 0, NULL, NULL, &si, &pi)) {
        //runas word is a hack to require UAC elevation
        ShellExecute(NULL, "runas", argv[2], params, NULL, SW_SHOWNORMAL);
}

И только ради цели - ссылки MSDN на ShellExecute и CreateProcess:

http://msdn.microsoft.com/en-us/library/bb762153%28v=vs.85%29.aspx

http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx