Как определить, является ли пользователь Администратором, даже если он не повышен
В моем приложении С# мне нужно проверить, является ли текущий пользователь членом группы "Администраторы". Он должен быть совместим как с Windows XP, так и с Windows 7.
В настоящее время я использую следующий код:
bool IsAdministrator
{
get
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
Проблема заключается в том, что этот метод возвращает false, если приложение запускается в Windows 7 с включенным UAC в качестве незанятого администратора. Как я могу определить, является ли пользователь администратором, даже если приложение запущено в качестве администратора без повышения?
Ответы
Ответ 1
Существует API Win32 GetTokenInformation
, который можно использовать для проверки текущего токена. Если возвращаемый токен является разделенным токеном, он, вероятно, является пользователем-администратором, который работает в режиме без повышения.
GetTokenInformation
имеет выходной параметр tokenInformation
, который принимает одно из трех значений:
- TokenElevationTypeDefault = 1
- TokenElevationTypeFull = 2
- TokenElevationTypeLimited = 3
Значение TokenElevantionTypeLimited указывает, что пользователь работает с разделенным токеном с ограниченными привилегиями. При увеличении значения TokenElevationTypeFull возвращается. У пользователя, не являющегося администратором, есть значение TokenElevationTypeDefault.
Существует полный пример кода для С# в http://www.davidmoore.info/2011/06/20/how-to-check-if-the-current-user-is-an-administrator-even-if-uac-is-on/
Ответ 2
Для любых людей VB.NET(я знаю, что вы там...), здесь версия, которую я придумал из разных источников, и, я думаю, оптимизирована для определения того, находится ли текущий пользователь (включая повышенный) определенную группу администраторов, машину или домен, с включенным или включенным UAC. (Множество кредитов для других должностей здесь и в других местах для этого!)
Во-первых, он использует статический null-able Boolean для сохранения статуса администратора, потому что, хотя базовая проверка выполняется быстро, полный тест может занять десятки секунд, поэтому вы хотите сделать это только один раз - если вообще, если вы может помочь ему.
Во-вторых, это ошибочно на стороне базового теста является неправильным/ложным, что обычно имеет место, если пользователь администрируется AD или если на локальном компьютере включен UAC. Поэтому, если он может решить, что пользователь является администратором, он будет.
В-третьих, вы можете добавлять или удалять критерии из AuthorizationGroups по своему усмотрению, но те, которые включены, охватывают большинство ситуаций.
Наконец, если что-то пойдет не так, вы получите False; если вы хотите получить ошибку, вы можете иметь ее, но лично я не вижу смысла.
Function IsAdministrator() As Boolean
Static bResult As Boolean? = Nothing
Try
If bResult Is Nothing Then
bResult = New WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator)
If Not bResult Then
Dim oContext As PrincipalContext = Nothing
Try 'to get a domain context first ...
Domain.GetComputerDomain()
oContext = New PrincipalContext(ContextType.Domain)
Catch
'... if it fails, fall through to a machine context
End Try
If oContext Is Nothing Then oContext = New PrincipalContext(ContextType.Machine)
Dim oPrincipal As UserPrincipal = UserPrincipal.FindByIdentity(oContext, WindowsIdentity.GetCurrent().Name)
If oPrincipal IsNot Nothing Then
bResult = oPrincipal.GetAuthorizationGroups().Any(Function(p) _
p.Sid.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid) OrElse
p.Sid.IsWellKnown(WellKnownSidType.AccountDomainAdminsSid) OrElse
p.Sid.IsWellKnown(WellKnownSidType.AccountAdministratorSid) OrElse
p.Sid.IsWellKnown(WellKnownSidType.AccountEnterpriseAdminsSid))
End If
End If
End If
Catch
bResult = False
End Try
Return bResult.GetValueOrDefault(False)
End Function
Ответ 3
Я знаю, что это уже давно, но я нашел способ работать хорошо во всех системах. Мне нужно было работать над .net 2 и другими решениями, такими как WinAPI и объекты управления, не удалось выполнить определенные версии Windows:
Запустите новый процесс с командой net localgroup administrators
и соответствующим образом проанализируйте вывод. Это работает как с включенным, так и с отключенным UAC и не требует повышенного процесса.
Ответ 4
Если вы являетесь администратором, вы можете временно отключить UAC из кода, а затем снова включить его. Ключ реестра
Ключ: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
Значение: EnableLUA
Установите для: 0 для отключения, 1 для включения
Итак, вы можете сделать что-то вроде
RegistryKey myKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\Policies\\System", true);
myKey.SetValue("EnableLUA", "1", RegistryValueKind.String);
Затем проверьте своего директора.. Это прекрасный хак, но его стоит сделать.