【问题标题】:Testing application for Administrative Running Rights测试行政运行权申请
【发布时间】:2011-08-31 05:48:36
【问题描述】:

我想要一个可靠的方法来测试应用程序是否通过 UAC 框运行并具有完全的管理权限。之前想在C:\Windows\下建个文件夹来测试,但是在其他电脑上运行却失败了!

UAC 框为计算机提供所有管理权限以执行任何操作(包括在需要权限的位置创建文件夹和创建文件),并确保任何被调用或创建的子程序也确实具有与父母。

是否有可靠的方法来测试我的应用程序是否已获得用户在运行应用程序时可以最大程度获得的所有管理权限?如果是的话,我会很高兴能够完成一段代码工作!

【问题讨论】:

    标签: windows vb.net uac


    【解决方案1】:

    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)
    

    【讨论】:

    • 在 VB.Net 中甚至有一个快捷方式:If My.User.IsInRole(ApplicationServices.BuiltInRole.Administrator) Then ...
    • C++ 等价于这段代码是:bool r=(gcnew WindowsPrincipal(WindowsIdentity::GetCurrent()))->IsInRole(WindowsBuiltInRole::Administrator);
    • @Wernfried 如果用户是全局管理员,则您的代码返回 True,如果用户以管理员身份运行应用程序则不会。
    【解决方案2】:

    经过一番摸索后,我发现如果用户的 UAC 设置为 Off 以外的任何值,则该问题的最常见解决方案会返回误报。

    这些天我的解决方案是这样做:

    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 检查。

    【讨论】:

      猜你喜欢
      • 2013-07-17
      • 2012-06-30
      • 2021-06-05
      • 2020-11-17
      • 1970-01-01
      • 2012-06-01
      • 2020-08-26
      • 1970-01-01
      相关资源
      最近更新 更多