Тестирование приложения для административного запуска прав VB.NET
Я хочу, чтобы надежный метод проверял, было ли приложение запущено через блок UAC и имеет полные права администратора. Ранее я думал о создании папки в C:\Windows\ для тестирования, но запуск ее на других компьютерах оказался неудачным!
Блок 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)
После долгих размышлений я обнаружил, что наиболее распространенные решения этого вопроса возвращают ложные отрицания, если для 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
проверять.