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

有帮助吗?

解决方案

该注册表项应该告诉您:

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

价值 EnableLUA (DWORD)

1 启用/ 0 或缺少残疾人

但这是假设您有权阅读它。

通过编程,您可以尝试读取用户的令牌并猜测它是否是启用了 UAC 的管理员(请参阅 这里)。虽然不是万无一失,但它可能会起作用。

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

其他提示

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

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

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

您不想检查 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;

您可以通过检查 DWORD 值来做到这一点 启用LUA 在以下注册表项中:

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

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

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的状态但尚未重新启动计算机,则该函数将返回不一致的结果。

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

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

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

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

如果没有检查 UAC 是否启用的方法,我们该如何处理呢?

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

对于发现此问题并正在寻找 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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top