Как программе получить права администратора во время ее выполнения
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.84] |
|
|
Правила раздела C/C++: Системное программирование и WinAPI
FAQ Сайта (C++)
FAQ Форума
Наши Исходники
Поиск по Разделу
MSDN Library Online (Windows Driver Kit)
Google
Как программе получить права администратора во время ее выполнения
|
Сообщ.
#1
,
|
|
|
|
Добрый вечер!
Программа первоначально запускается под обычным пользователем. Затем ей необходимо операции, для которых требуются админские права. Можно ли программно получить - с запросом логина/пароля от ОС также как это делается при запуске программы сразу с "Run as Administrator" ? Самое простое решение, наверное - запустить свою копию по типу "Run as Administrator", но меня интересует - без перезапуска - можно это сделать, а если да, то как ? |
|
Сообщ.
#2
,
|
|
|
|
Увы, нет. Для получения повышенных прав требуется добавление привилегий в токен приложения, но такой возможности не существует. Привилегию можно разрешить, запретить или удалить из токена, но добавить её невозможно. Для этого нужно создать новый токен, уже имеющий нужную привилегию, пусть и отключённую по дефолту, однако созданный т.о. токен не может быть назначен уже имеющемуся процессу, если только он не сервис. Новый процесс на его основе можно создать, однако для обычного пользователя даже создание токена с повышенными привилегиями непосильная задача: для добавления в токен привилегий нужно уже обладать как минимум этими привилегиями.
P.S. Не следует путать привилегии и права доступа. Это разные вещи. Права доступа относятся к действиям с объектами ОС, привилегии же определяют действия, не связанные с объектами. Например, отладка процессов, перезагрузка итп. Добавлено P.P.S. Кажется слишком строго, однако отсутствие такой возможности грамотное решение. В противном случае любой процесс бесконтрольно мог бы повышать свои привилегии без вмешательства пользователей, и грош цена такой ОСи. |
|
Сообщ.
#3
,
|
|
|
|
Qraizer, спасибо!
А каким образом программа может узнать запущена она под админом или нет ? И каким образом она может перезапуститься уже под администратором ? |
|
Сообщ.
#4
,
|
|
|
|
ChatGPT рекомендуэ
Цитата Lun2 @ А каким образом программа может узнать запущена она под админом или нет ? ![]() ![]() #include <windows.h> #include <stdio.h> BOOL IsRunAsAdmin() { BOOL fIsRunAsAdmin = FALSE; DWORD dwError = 0; PSID pAdministratorsGroup = NULL; // Получаем SID группы "Administrators" (BUILTIN\Administrators) SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdministratorsGroup)) return FALSE; // Проверяем, входит ли текущий токен в эту группу и включена ли привилегия if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin)) { dwError = GetLastError(); fIsRunAsAdmin = FALSE; } if (pAdministratorsGroup) FreeSid(pAdministratorsGroup); return fIsRunAsAdmin; } Цитата Lun2 @ И каким образом она может перезапуститься уже под администратором ? ![]() ![]() #include <windows.h> #include <shellapi.h> #pragma comment(lib, "shell32.lib") BOOL ElevateCurrentProcess() { wchar_t szPath[MAX_PATH]; if (GetModuleFileNameW(NULL, szPath, ARRAYSIZE(szPath)) == 0) return FALSE; SHELLEXECUTEINFOW sei = { sizeof(sei) }; sei.lpVerb = L"runas"; // запрос UAC sei.lpFile = szPath; // путь к нашему exe sei.hwnd = NULL; sei.nShow = SW_NORMAL; // Можно передать параметры, если нужно // sei.lpParameters = L"--some-param"; if (ShellExecuteExW(&sei)) { // Успешно запустили elevated версию — можно завершиться return TRUE; } else { DWORD dwError = GetLastError(); if (dwError == ERROR_CANCELLED) // пользователь нажал "Нет" в UAC MessageBoxW(NULL, L"Требуются права администратора!", L"Ошибка", MB_ICONERROR); return FALSE; } } Чтобы UAC вообще показывал кнопку «Запуск от имени администратора», в exe должен быть встроен манифест с requireAdministrator или asInvoker. Самый простой способ — добавить в проект файл app.manifest с: ![]() ![]() <requestedExecutionLevel level="asInvoker" uiAccess="false"/> или ![]() ![]() <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/> Вощем - копай в эту сторону! ИИ часто помогает, но и не менее часто несёт лютую пургу. |
|
Сообщ.
#5
,
|
|
|
|
Цитата Lun2 @ И каким образом она может перезапуститься уже под администратором ? Наверное, так: ![]() ![]() ::CreateProcessWithLogonW (...); И не только под администратором, а вообще под любым юзером. Надо указать юзера, пароль и командную строку. Диалог ввода юзера и пароля надо самому смастерить (если нужно). |
|
Сообщ.
#6
,
|
|
|
|
Цитата Lun2 @ А каким образом программа может узнать запущена она под админом или нет ? ![]() ![]() IsUserAnAdmin |
|
Сообщ.
#7
,
|
|
|
|
Цитата ЫукпШ @ IsUserAnAdmin С некоторыми оговорками ... https://stackoverflow.com/questions/2993964...-and-the-user-a |
|
Сообщ.
#8
,
|
|
|
|
Цитата ЫукпШ @ Цитата Lun2 @ 28 ноября, 01:22 И каким образом она может перезапуститься уже под администратором ? Наверное, так: CollapsedWrap disabledLine numbers off ::CreateProcessWithLogonW (...); И не только под администратором, а вообще под любым юзером. Надо указать юзера, пароль и командную строку. Диалог ввода юзера и пароля надо самому смастерить (если нужно). ЫукпШ, спасибо за ответ! А если хочу, чтобы система сама выдавала запрос на ввод логина пароля - как это сделать. Ведь когда в проводнике запускаю под админом, как я понял, выдается "системный" диалог для ввода юзера и пароля - лично моей программе эти данные не нужны... |
|
Сообщ.
#9
,
|
|
|
|
Цитата Majestio @ Чтобы UAC вообще показывал кнопку «Запуск от имени администратора», в exe должен быть встроен манифест с requireAdministrator или asInvoker. Самый простой способ — добавить в проект файл app.manifest с: Majestio,Спасибо! Про манифест знаю. Задача в том, что изначально программа запускается без прав админа, а для определенных задача они становятся необходимыми. Так что изначально использовать манифест - это не, там сразу под админом пойдем... |
|
Сообщ.
#10
,
|
|
|
|
Цитата Lun2 @ А если хочу, чтобы система сама выдавала запрос на ввод логина пароля - как это сделать. Как то раз я тоже искал, как это сделать. И не нашёл. Поэтому этот не сложный диалог делал сам. Вот пример подобного Однако, вроде бы такая winapi функция имеется, но я так не делал. вот она |
|
Сообщ.
#11
,
|
|
|
|
Цитата ЫукпШ @ Как то раз я тоже искал, как это сделать. И не нашёл. Поэтому этот не сложный диалог делал сам. Вот пример подобного Однако, вроде бы такая winapi функция имеется, но я так не делал. вот она Спасибо! |