【问题标题】:How can I check that an executable is being run as an administrator?如何检查可执行文件是否以管理员身份运行?
【发布时间】:2016-12-11 07:00:03
【问题描述】:

我正在用 c++/c 编写一个应用程序。如何检测进程是否以管理员身份启动(右键以管理员身份运行)?

【问题讨论】:

  • 根据您的术语,我相信此应用程序旨在在 Windows 上运行。对吗?
  • 很抱歉,我忘了提到操作系统:p 是的,它是 windows

标签: c windows winapi elevated-privileges


【解决方案1】:

假设问题陈述是“如何确定我的进程是否在 UAC 下被提升”,

  1. 检查 UAC 是否启用
  2. 检查IsUserAnAdmin()是否返回true
  3. 检查进程令牌的提升类型是TokenElevationTypeFull

如果所有三个测试都为真,则您的进程已在 UAC 下提升。请注意,GetProcessElevationType 本身检查可能就足够了,但在我们自己的代码中,我们会执行其他检查,以防将来有其他类型的拆分令牌。

详情:

  1. 检查 UAC 是否启用

可能还有其他方法可以做到这一点,但最简单的方法是查看注册表。如果值EnableLUA 存在于注册表项HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System 下,则启用UAC。

  1. 检查IsUserAnAdmin()是否返回true

这很简单——只需调用IsUserAnAdmin() 函数。请注意,此功能已弃用;你也可以使用CheckTokenMembership()函数。

  1. 检查进程令牌的提升类型是TokenElevationTypeFull

您可以使用以下函数获取令牌的海拔类型:

// TokenElevationTypeDefault -- User is not using a split token. (e.g. UAC disabled or local admin "Administrator" account which UAC may not apply to.)
// TokenElevationTypeFull    -- User has a split token, and the process is running elevated.
// TokenElevationTypeLimited -- User has a split token, but the process is not running elevated.
bool GetProcessElevationType(TOKEN_ELEVATION_TYPE *pOutElevationType)
{
    *pOutElevationType = TokenElevationTypeDefault;
    bool fResult = false;

    HANDLE hProcToken = NULL; 

    if (::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &hProcToken))
    {
        DWORD dwSize = 0;
        TOKEN_ELEVATION_TYPE elevationType = TokenElevationTypeDefault;

        if (::GetTokenInformation(hProcToken, TokenElevationType, &elevationType, sizeof(elevationType), &dwSize)
        &&  dwSize == sizeof(elevationType))
        {
            *pOutElevationType = elevationType;
            fResult = true;
        }

        ::CloseHandle(hProcToken);
    }

    return fResult;
}

【讨论】:

  • 我对第 1 步持怀疑态度,因为我认为无法保证注册表项将继续存在于未来的 Windows 版本中。还应该注意的是,在很多情况下(显然不是这个,但更多时候)你真正想知道的只是你是否有管理员权限,即,只是第 2 步。
  • @HarryJohnston 请注意,该注册表项 is documented
  • 呃,我认为这不是正确的链接。这是 XML 文件中的设置,而不是注册表项。无论如何,如果我没记错的话,可以通过组策略配置密钥,因此它可能在该上下文中记录 - 但组策略不承诺向前兼容性。 (我不知道你为什么还要麻烦第 1 步,因为如果禁用 UAC,第 3 步将始终返回 TokenElevationTypeDefault?)
  • @HarryJohnston 正如我在回答中所说,“请注意,GetProcessElevationType 检查本身就足够了”。这正是我们在代码中所做的。随意做其他事情:)
  • stackoverflow.com/a/8196291/1836776 是另一种可能更简单的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-31
  • 2017-09-15
  • 1970-01-01
  • 2010-12-22
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
相关资源
最近更新 更多