在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程序开发.