Как узнать, запущена программа с правами администратора или нет
Иногда возникает задача узнать, запущена ли программа под администраторской учеткой или же обычного пользователя. Для чего это нужно? Ну, например мы написали крутую софтину, выполняющую некие действия с системой (например свой собственный редактор реестра). Для редактирования некоторых веток (например HKEY_LOCAL_MACHINE), требуются права админа. А вдруг программа запущена без соответствующих привилегий, то тогда мы ничего не сможем сделать — это раз, система нам будет показывать непонятные на первый взгляд ошибки — это два. Одна из самых частых в такой ситуации — ошибка с кодом 5 (ERROR_ACCESS_DENIED). С проверкой на «вшивость» можно говорить пользователю, что нужно запустить программу с правами администратора и смело закрываться.
Погуглив, не нашел ничего подходящего. Может просто плохо искал?
Обратившись к крутой справочной системе, входящей в состав Delphi 7, был обнаружен кусок кода, который как раз за это отвечает. Но… Он на Си. Ну ничего, попыхтев немного мне всетаки удалось переписать его на Delphi.
Отступление:
исходник функции на Си можно найти в Help -> Windows SDK -> Поиск.
Если запускаете поиск первый раз, то нужно выбрать пункт «Обеспечить максимальные возможности поиска».
Если запускаете не первый раз, то нужно нажать на кнопку «Перестроить…» и выбрать пункт «Обеспечить максимальные возможности поиска».
После этого в поле поиска (1 поле) ввести «admin», а в результатах поиска (2 поле) выбрать первый пункт «admin». И в третьем поле, там где нас просят выбрать нужный раздел, выбираем раздел «Determining Whether the User is an Administrator». Жмем «Показать» и копипастим код:)
Код на Delphi:
function isAdmin: Boolean; { Объявление констант, которых в delphi я не нашел } const SECURITY_BUILTIN_DOMAIN_RID = $00000020; DOMAIN_ALIAS_RID_ADMINS = $00000220; var hProcess, hAccessToken: Cardinal; InfoBuffer: array [0..1023] of Char; ptgGroups: PTokenGroups; dwInfoBufferSize: DWORD; psidAdmins: PSID; siaNtAuthority: TSidIdentifierAuthority; x: UINT; begin { Получаем Token нашего приложения } hProcess := GetCurrentProcess(); { Обнуляем память и заносим в последний элемент 5. Это нужно для того что бы "формат" данных выглядел так [0, 0, 0, 0, 0, 5] тупым присваиванием не прокатило. Откуда я это знаю? Подсмотрел в VC, как и те две константы, что объявлены в начале:) } ZeroMemory(@siaNtAuthority.Value, sizeof(Char)*6); siaNtAuthority.Value[5] := 5; { даем указатель ptgGroups на InfoBuffer } ptgGroups := PTokenGroups(@InfoBuffer); { Попытка открыть процесс и получить инфу о нем } if not OpenProcessToken(hProcess, TOKEN_READ, hAccessToken) then begin Result := false; Exit; end; { Пытаемся получить информаци о првах доступа, одновременно заполная все что нужно } if not (getTokenInformation(hAccessToken, TokenGroups, @InfoBuffer, High(InfoBuffer) + 1, dwInfoBufferSize)) then begin Result := false; Exit; end; { Распределяем и инициализируем идентификатор безопасности (SID) с восьмью полномочиями } AllocateAndInitializeSid(siaNtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, psidAdmins); { Тут вроде происходит собственно проверка на то, является ли процесс запущенный с правами админа } for x := 0 to ptgGroups.GroupCount - 1 do if EqualSid(psidAdmins, ptgGroups.Groups[x].Sid) then begin FreeSid(psidAdmins); Result := true; Exit; end; FreeSid(psidAdmins); Result := false; end;
Воть. За коменты сильно не бейте, писал от себя, так, как я это понимаю +переводы SDK, весьма скудными знаниями английского((
Надеюсь статейка будет полезна. (на форуме где то видел похожую тему).
спасибо за информацию! очень полезная..
Есть еще один очень тупой, но очень простой метод, который позволяет узнать это на много быстрее. Нужно попробовать создать файл в любой защищенной области в файловой системе или в реестре. Если ошибка, то отваливаем. Метод в заметке лучше и позволяет узнать более точно, под кем работает, но в большинстве случаев, достаточно ответа да/нет.
Статья ваша действительно оказалась полезной
2Михаил
Если у пользователя стоят права «Опытный пользователь», то создать файл в защищенной области можно, но изменять нельзя. Тем более, может возникнуть ситуация когда файл с таким именем существует и не будет доступа создать файл.
Некоторые антивирусы и фаеры, «следят» за реестром. Он (защитное ПО) спросит «Разрешить создать ключ или нет?», кто-то может ответить что нет, вывалится ошибка о не достаточном доступе и прога скажет, что нужно запускаться от админа, а она может уже запущена от админа!
Так что я думаю этот способ не подойдет:)
Чуть попозже, все таки почитаю конкретно про функции которые были использованы и подправлю коменты.
под вин7 почемуто всегда выдает, что нет прав админа 😕 ❗
2yugovoo
Опиши процесс, как ты запускаешь прогу.
К сожалению, не могу проверить под вин7(
Большое спасибо, как раз это и искал, а то никак не мог хост изменить…
const
SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority =
(Value: (0, 0, 0, 0, 0, 5));
SECURITY_BUILTIN_DOMAIN_RID = $00000020;
DOMAIN_ALIAS_RID_ADMINS = $00000220;
.
.
.
function TRegistration.IsAdmin: Boolean;
var
hAccessToken: THandle;
ptgGroups: PTokenGroups;
dwInfoBufferSize: DWORD;
psidAdministrators: PSID;
x: Integer;
bSuccess: BOOL;
begin
Result := False;
bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,
hAccessToken);
if not bSuccess then
begin
if GetLastError = ERROR_NO_TOKEN then
bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
hAccessToken);
end;
if bSuccess then
begin
GetMem(ptgGroups, 1024);
bSuccess := GetTokenInformation(hAccessToken, TokenGroups,
ptgGroups, 1024, dwInfoBufferSize);
CloseHandle(hAccessToken);
if bSuccess then
begin
AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, psidAdministrators);
{$R-}
for x := 0 to ptgGroups.GroupCount — 1 do
if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then
begin
Result := True;
Break;
end;
{$R+}
FreeSid(psidAdministrators);
end;
FreeMem(ptgGroups);
end;
end;
Точно работает по Win7 и под все семейство NT
Недавно Станислав Подгорный(технический директор), в сотрудничестве с Александром Вербовским(PHP разработчик) разработали уникальное приложение под названием “My Market Value” , позволяющее проследить за процессами на рынке труда и соизмерить свои силы с ожиданиями по зароботной плате.
Даное приложение являеться новинкой в мире IT и не имеет аналогов в Украине и за рубежом. Благодаря уникальной разработке двух ярких индивидуальностей и истинных профессионалов своего дела, разработчики нашей страны получили возможность реально оценивать свои силы в сфере IT.
Оцените свои возможности, проследите за стремительно изменяющимися технологиями, освойте новые направления и творчески подходите к своим возможностям.
Теперь, оценить свои знания и навыки легко – несколько кликов – и вы в мире IT, в мире несоизмеримых возможностей и перспектив.
http://apps.facebook.com/mymarketvalue
Сделайте шаг навстречу своей мечте, получите работу, на которую вы заслуживаете и оцените свои таланты по достоинству!
Неплохое решение, но это можно и зделать по другому. Правда ваш код более компактный и вообще зачем искать иное решение.
23432432432
2343242343243
проголосуйте на стене
широков или измайлов?
http://vk.com/id17072313
Стыдно должно быть. Взял чужой код и выдаешь за свой. Думай своей тупой головой, чмо позорное