Тестирование приложения для прав администратора - PullRequest
9 голосов
/ 23 мая 2011

Я хочу, чтобы верный метод проверял, было ли приложение запущено через блок UAC и имеет полные права администратора.Ранее я думал о создании папки в C: \ Windows \ для тестирования, но запуск ее на других компьютерах оказался неудачным!

Блок UAC предоставляет всем администраторам права администратора на все действия (включая созданиепапки и создание файлов в местах, для которых нужны соответствующие права), а также гарантирует, что любая так называемая или созданная дочерняя программа также имеет те же права, что и родительская.

Существует ли надежный способ проверки, если мойприложению были предоставлены все административные права, которые я могу максимально получить от пользователя при запуске приложения или нет?Если да, я был бы рад иметь кусочек кода!

Ответы [ 2 ]

19 голосов
/ 23 мая 2011

C #:

using System.Security.Principal;

...

var identity = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(identity);
bool isElevated = principal.IsInRole(WindowsBuiltInRole.Administrator);

VB.Net:

Imports System.Security.Principal

...

Dim identity = WindowsIdentity.GetCurrent()
Dim principal = new WindowsPrincipal(identity)
Dim isElevated as Boolean = principal.IsInRole(WindowsBuiltInRole.Administrator)
0 голосов
/ 12 марта 2019

После долгих раздумий я обнаружил, что наиболее распространенные решения этого вопроса возвращают ложные отрицания, если для UAC пользователя установлено любое значение, кроме Выкл. .

Мое решение в эти дни состоит в том, чтобы сделать это:

Imports System.Security.Principal
Imports System.DirectoryServices.AccountManagement
Imports System.DirectoryServices.ActiveDirectory
Imports Microsoft.VisualBasic.ApplicationServices

''' <summary>Checks whether the current user is belongs to any Administrators groups.</summary>
''' <param name="AuthGroups">Optional. A flag indicating whether to use GetAuthorizationGroups instead of the - faster - GetGroups. Default=true.</param>
''' <returns>True if the user belongs to an Administrators group, false otherwise.</returns>
Public Function IsAdministrator(
    Optional ByVal AuthGroups As Boolean = True) 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 'Domain check first
                    Domain.GetComputerDomain()
                    oContext = New PrincipalContext(ContextType.Domain)
                Catch
                    'Fall through to machine check
                End Try
                If oContext Is Nothing Then oContext = New PrincipalContext(ContextType.Machine)
                'Dim oPrincipal As UserPrincipal = UserPrincipal.FindByIdentity(oContext, WindowsIdentity.GetCurrent().Name) ' Don't use - slow
                Using oSearchUser As Principal = New UserPrincipal(oContext)
                    oSearchUser.SamAccountName = WindowsIdentity.GetCurrent().Name
                    Using oSearcher As PrincipalSearcher = New PrincipalSearcher(oSearchUser)
                        Using oUser As Principal = oSearcher.FindOne()
                            If oUser IsNot Nothing Then
                                If AuthGroups Then
                                    bResult = CType(oUser, UserPrincipal).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))
                                Else
                                    bResult = oUser.GetGroups().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 Using
                    End Using
                End Using
            End If
        End If
    Catch
        bResult = False
    End Try
    Return bResult.GetValueOrDefault(False)
End Function

Этот метод представляет собой совокупность нескольких других ответов, поэтому я возьму на себя ответственность только за упаковку его в функцию, которая будет выполняться только один раз, и поэтому, если есть небольшая задержка из-за сбоя, вы может спрятать его при запуске.

Аргумент AuthGroups позволяет выбрать более тщательную, рекурсивную проверку AuthorizationGroups (по умолчанию) или более быструю проверку Groups.

...