Как определить, является ли пользователь Администратором, даже если он не повышен

В моем приложении С# мне нужно проверить, является ли текущий пользователь членом группы "Администраторы". Он должен быть совместим как с 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);

Затем проверьте своего директора.. Это прекрасный хак, но его стоит сделать.