在我的C#应用程序中,我需要检查当前用户是否是Administrators组的成员。它需要与Windows XP和Windows 7兼容。
目前,我使用以下代码:
bool IsAdministrator
{
get
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
问题是,如果应用程序在Windows 7上运行且UAC作为非提升管理员打开,则此方法返回false。即使应用程序作为非提升管理员运行,如何确定用户是否为管理员?
答案 0 :(得分:18)
可以使用Win32 API GetTokenInformation
来检查当前令牌。如果返回的令牌是拆分令牌,则它可能是在非升级模式下运行的管理员用户。
GetTokenInformation
有一个输出参数tokenInformation
,它取三个值中的一个:
TokenElevantionTypeLimited的值表示用户正在使用具有有限权限的拆分令牌运行。提升时,返回TokenElevationTypeFull值。非管理员用户的值为TokenElevationTypeDefault。
上有一个完整的C#代码示例答案 1 :(得分:1)
对于任何VB.NET人员(我知道你在那里......),这里是我从各种来源编造的版本,我认为是优化的,以确定当前用户(包括提升的)是否在已启用或未启用UAC的已定义管理员组,计算机或域。 (很多信用到这里和其他地方的其他帖子!)
首先,它使用静态无效布尔值来保留管理员状态,因为尽管基本检查很快,但完整测试可能需要几十秒,所以你只想做一次 - 如果你有的话可以帮助它。
其次,它在基本测试方面不正确/错误,如果用户是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
答案 2 :(得分:0)
我知道这已经过时了,但我发现以下方法可以在所有系统中正常运行。我需要它来处理.net 2和其他解决方案,如WinAPI和管理对象在某些版本的Windows上失败:
启动运行命令net localgroup administrators
的新进程并适当地解析输出。这适用于启用和禁用UAC,并且不需要升级过程。
答案 3 :(得分:-5)
如果您是管理员,则可以暂时从代码中禁用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);
然后检查你的校长..这是一种黑客攻击,但值得一试。