当前位置: 代码迷 >> VC/MFC >> 怎么像vs2010那样在需要时提升权限
  详细解决方案

怎么像vs2010那样在需要时提升权限

热度:95   发布时间:2016-05-02 03:39:49.0
如何像vs2010那样在需要时提升权限?
在vs2010中如果编译一个有管理员权限的执行程序,当你调试的时候,会提醒你当前vs2010的权限不够,需要以管理员权限重新启动,确认后vs2010就会以管理员权限重新启动。如何实现这种功能?
------解决思路----------------------

// 是否以管理员权限运行
bool LongUI::CUIManager::IsRunAsAdministrator() noexcept {
    BOOL fIsRunAsAdmin = FALSE;
    PSID pAdministratorsGroup = nullptr;
    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
    ::AllocateAndInitializeSid(
        &NtAuthority,
        2,
        SECURITY_BUILTIN_DOMAIN_RID,
        DOMAIN_ALIAS_RID_ADMINS,
        0, 0, 0, 0, 0, 0,
        &pAdministratorsGroup
    );
    // 成功? 清理资源
    if (pAdministratorsGroup) {
        ::CheckTokenMembership(nullptr, pAdministratorsGroup, &fIsRunAsAdmin);
        ::FreeSid(pAdministratorsGroup);
        pAdministratorsGroup = nullptr;
    }
    // 返回结果
    return fIsRunAsAdmin != 0;
}

// 提升权限
bool LongUI::CUIManager::TryElevateUACNow(const wchar_t* parameters, bool exit) noexcept {
    if (!CUIManager::IsRunAsAdministrator()) {
        wchar_t szPath[MAX_PATH];
        // 获取实例句柄
        if (::GetModuleFileNameW(NULL, szPath, ARRAYSIZE(szPath))) {
            // Launch itself as admin
            SHELLEXECUTEINFO sei = { 0 };
            sei.cbSize = sizeof(sei);
            sei.lpVerb = L"runas";
            sei.lpFile = szPath;
            sei.lpParameters = parameters;
            sei.hwnd = nullptr;
            sei.nShow = SW_NORMAL;
            // 执行
            if (!::ShellExecuteExW(&sei)) {
                DWORD dwError = ::GetLastError();
                assert(dwError == ERROR_CANCELLED && "anyelse?");
                return false;
            }
            else if(exit) {
                // 退出
                UIManager.Exit();
            }
        }
    }
    return true;
}

把项目中核心代码复制来了
------解决思路----------------------
应该是需要的时候,调用ShellExecuteEx,传入runas,以管理员权限重新运行
------解决思路----------------------
应该有静态和动态两种方式, 动态应该有API来判断权限, 并重新申请权限. 

而静态的就比较好实施, 如果你断定你的程序是肯定需要管理员权限的. 

1. 可以在程序里加入一个.Manifest 文件来要求管理员权限运行. 具体可以百度. 加入该资源后, 程序会自动带上盾牌.

2. 二楼的ShellExecuteExW+runas, 也会自动尝试以管理员提示, 但程序不会带盾. 一般用作非GUI程序开发. 

  相关解决方案