如何检测Vista UAC是否已启用?

时间:2008-09-18 18:41:37

标签: windows-vista uac

我需要我的应用程序以不同的方式运行,具体取决于Vista UAC是否启用。我的应用程序如何在用户的计算机上检测UAC的状态?

8 个答案:

答案 0 :(得分:18)

此注册表项应告诉您:

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

价值EnableLUA (DWORD)

1已启用/ 0或已禁用

但这假设您有权阅读它。

以编程方式,您可以尝试读取用户的令牌并猜测它是否是在启用UAC的情况下运行的管理员(请参阅here)。不是万无一失,但可能有用。

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

答案 1 :(得分:4)

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

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

该帖子中的代码不只是从注册表中读取。如果启用了UAC,则您可能无权从注册表中读取该内容。

答案 2 :(得分:4)

您不想检查UAC是否已启用;那不会告诉你什么。

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

您想查看if the user is running with administrative privileges using 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;

答案 3 :(得分:3)

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

HKLM /软件/微软/视窗/ 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的状态但尚未重新启动计算机,则此函数将返回不一致的结果。

答案 4 :(得分:2)

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

中的注册表值

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

答案 5 :(得分:1)

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

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

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

也许在这个例子中检查用户是否以管理员权限运行是正确的,但谁知道呢?微软提供的指导,充其量,iffy,如果不仅仅是彻头彻尾的混淆。

答案 6 :(得分: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

答案 7 :(得分:-1)

AFAIK,UAC是本地用户或组的apolicy设置。所以你可以在.Net内阅读这个属性。很抱歉没有更多细节,但我希望这有帮助