c - 如何检查可执行文件是否以管理员身份运行?

标签 c windows winapi elevated-privileges

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

最佳答案

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

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

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

详细信息:

  1. 检查 UAC 是否启用

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

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

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

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

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

// 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;
}

关于c - 如何检查可执行文件是否以管理员身份运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38779450/

相关文章:

C-Mysql-警告 : assignment from incompatible pointer type

c - 传递一个数组作为参数

php - 在 php 中制作作业队列系统的最佳实践是什么?

windows - 在 WinRT 应用程序中检测击键

windows - 如何确定文件的碎片化程度?

c - 这个C程序有什么问题?

c - 链表 - 在中间插入,链接新节点

c# - Windows 7 和 8 中的系统范围设置 - 注册表不再有用?

c# - 如何在 C# 中自动引入 Win32 API 声明?

c++ - 如何在工作线程(非 UI 线程)中创建模态对话框?