首页 / 知识

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

2023-04-17 07:50:00

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

How to detect whether Vista UAC is enabled?

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


此注册表项应告诉您:

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

EnableLUA (DWORD)

启用1 / 0或禁用丢失

但这假设您有权阅读它。

您可以通过编程方式尝试读取用户的令牌,并猜测它是否是启用了UAC的管理员(请参见此处)。并非万无一失,但它可能会起作用。

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


您不想检查是否启用了UAC。那什么都没告诉你。

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

您想使用CheckTokenMembership检查用户是否正在以管理特权运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
///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;


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

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

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


您可以通过检查以下注册表项中的DWORD值EnableLUA来完成此操作:

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

如果该值为0(或不存在),则UAC为OFF。如果存在且非零,则UAC处于打开状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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的状态但尚未重新启动计算机,则此功能将返回不一致的结果。


这篇文章相当古老,但是我想评论一下"为什么需要知道"和"检查令牌成员身份"部分。

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

我们如何做到这一点而又无法检查是否启用了UAC?

在这种情况下,也许检查用户是否以管理员权限运行是正确的事情,但是谁知道呢?微软给出的指导充其量甚至是完全不确定的,即使不是完全令人困惑的。


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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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

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


启用检测应用程序计算

最新内容

相关内容

猜你喜欢