22

我需要我的应用程序根据 Vista UAC 是否启用而表现不同。我的应用程序如何检测用户计算机上的 UAC 状态?

4

8 回答 8

18

此注册表项应告诉您:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System

价值 EnableLUA (DWORD)

1启用/0或缺少禁用

但这假设您有权阅读它。

以编程方式,您可以尝试读取用户的令牌并猜测它是否是启用 UAC 的管理员(请参阅此处)。不是万无一失的,但它可能会奏效。

这里的问题更多的是“你为什么需要知道”——它与答案有关。实际上,没有 API,因为从操作系统行为的角度来看,重要的是用户是否是管理员 - 他们如何选择以管理员身份保护自己是他们的问题。

于 2008-09-18T18:49:26.200 回答
4

这篇文章有 C# 中的示例代码,用于测试 UAC 是否打开以及当前应用程序是否已获得提升的权限。您可以下载代码并根据需要进行解释。还链接了一个在 C++ 中显示相同的示例

http://www.itwriting.com/blog/198-c-code-to-detect-uac-elevation-on-vista.html

那篇文章中的代码不仅仅是从注册表中读取的。如果启用了 UAC,您可能无权从注册表中读取它。

于 2008-09-18T18:43:33.750 回答
4

您不想检查是否启用了 UAC;这并不能告诉你任何事情。

我可以成为禁用 UAC 的标准用户。

您想使用以下命令检查用户是否以管理权限运行CheckTokenMembership

///This function tells us if we're running with administrative permissions.
function IsUserAdmin: Boolean;
var
    b: BOOL;
    AdministratorsGroup: PSID;
begin
    {
        This function returns true if you are currently running with 
               admin privileges.
        In Vista and later, if you are non-elevated, this function will 
               return false (you are not running with administrative privileges).
        If you *are* running elevated, then IsUserAdmin will return 
               true, as you are running with admin privileges.

        Windows provides this similar function in Shell32.IsUserAnAdmin.
               But the function is depricated, and this code is lifted from the 
               docs for CheckTokenMembership: 
               http://msdn.microsoft.com/en-us/library/aa376389.aspx
    }

    {
        Routine Description: This routine returns TRUE if the caller's
        process is a member of the Administrators local group. Caller is NOT
        expected to be impersonating anyone and is expected to be able to
        open its own process and process token.
        Arguments: None.
        Return Value:
            TRUE - Caller has Administrators local group.
            FALSE - Caller does not have Administrators local group.
    }
    b := AllocateAndInitializeSid(
            SECURITY_NT_AUTHORITY,
            2, //2 sub-authorities
            SECURITY_BUILTIN_DOMAIN_RID,    //sub-authority 0
            DOMAIN_ALIAS_RID_ADMINS,        //sub-authority 1
            0, 0, 0, 0, 0, 0,               //sub-authorities 2-7 not passed
            AdministratorsGroup);
    if (b) then
    begin
        if not CheckTokenMembership(0, AdministratorsGroup, b) then
         b := False;
        FreeSid(AdministratorsGroup);
    end;

    Result := b;
end;
于 2011-05-24T18:02:59.117 回答
3

您可以检查以下注册表项中的 DWORD 值EnableLUA :

HKLM/软件/微软/Windows/CurrentVersion/策略/系统

如果值为 0(或不存在),则 UAC 为 OFF。如果它存在且非零,则 UAC 为 ON:

BOOL IsUacEnabled( )
{
    LPCTSTR pszSubKey = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
    LPCTSTR pszValue = _T("EnableLUA");
    DWORD dwType = 0;
    DWORD dwValue = 0;
    DWORD dwValueSize = sizeof( DWORD );

    if ( ERROR_SUCCESS != SHGetValue( HKEY_LOCAL_MACHINE, pszSubKey, pszValueOn, 
        &dwType, &dwValue, &dwValueSize) )
    {
            return FALSE;
    }

    return dwValue != 0;
} 

注意,如果用户改变了 UAC 的状态但还没有重启电脑,这个函数会返回不一致的结果。

于 2008-09-18T18:52:41.357 回答
2

检查 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System 中的注册表值

EnableLUA 值确定 UAC 是否处于活动状态。

于 2008-09-18T18:43:19.930 回答
2

这篇文章相当古老,但我想评论“你为什么需要知道”和“检查令牌成员资格”位。

事实是微软自己的文档说“如果用户帐户控制已关闭并且标准用户尝试执行需要提升的任务”我们应该提供错误而不是显示按钮和/或与 UAC 屏蔽的链接尝试提升。有关详细信息,请参阅底部的http://msdn.microsoft.com/en-us/library/windows/desktop/aa511445.aspx 。

如果没有检查 UAC 是否启用的方法,我们如何做到这一点?

在这种情况下,也许检查用户是否以管理员权限运行是正确的做法,但谁知道呢?微软提供的指导充其量是不确定的,如果不是完全令人困惑的话。

于 2012-10-03T01:23:23.203 回答
1

对于发现此问题并正在寻找 VBScript 解决方案的任何其他人。这是我想出的检测是否启用了 UAC,如果启用,则以提升的权限重新启动我的脚本。只需将您的代码放在 Body() 函数中。如果我编写代码以始终启动提升,我发现 XP 和 Windows 7 之间的可移植性存在问题。如果没有 UAC,则使用此方法绕过海拔高度。还应考虑启用了 UAC 的 2008 及更高版本的服务器版本。

On Error Resume Next
UACPath = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA"
Dim WshShell
Set WshShell = CreateObject("wscript.Shell")
UACValue = WshShell.RegRead(UACPath)
If UACValue = 1 Then
'Run Elevated
    If WScript.Arguments.length =0 Then
      Set objShell = CreateObject("Shell.Application")
      'Pass a bogus argument with leading blank space, say [ uac]
      objShell.ShellExecute "wscript.exe", Chr(34) & _
      WScript.ScriptFullName & Chr(34) & " uac", "", "runas", 1
      WScript.Quit
    Else 
        Body()
    End If
Else
Body()
End If

Function Body()
MsgBox "This is the body of the script"
End Function
于 2013-02-15T16:42:21.513 回答
-1

AFAIK,UAC 是本地用户或组的策略设置。因此,您可以从 .Net 中读取此属性。抱歉没有更多细节,但我希望这会有所帮助

于 2008-09-18T18:43:42.690 回答