有的时候要操作 C 盘数据或者干点什么,就要管理员权限
win api 还挺方便
// 判断程序现在是否已有管理员权限
BOOL IsRunAsAdministrator()
{
BOOL fIsRunAsAdmin = FALSE;
DWORD dwError = ERROR_SUCCESS;
PSID pAdministratorsGroup = NULL;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if (!AllocateAndInitializeSid(
&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pAdministratorsGroup))
{
dwError = GetLastError();
goto Cleanup;
}
if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin))
{
dwError = GetLastError();
goto Cleanup;
}
Cleanup:
if (pAdministratorsGroup)
{
FreeSid(pAdministratorsGroup);
pAdministratorsGroup = NULL;
}
if (ERROR_SUCCESS != dwError)
{
throw dwError;
}
return fIsRunAsAdmin;
}
/**
* @brief 程序获取管理员权限
* @param[in] Param: 程序的运行参数
* @param[in] Showcmd: 程序的显示方式
*
* @return 0 - 获取管理员权限失败
* 1 - 获取管理员权限成功
* 2 - 已有管理员权限
*/
short GetWindowsAdmin(LPCTSTR Param = L"", int Showcmd = SW_SHOWDEFAULT)
{
if (IsRunAsAdministrator()) return 2;
TCHAR Path[MAX_PATH];
ZeroMemory(Path, MAX_PATH);
::GetModuleFileName(NULL, Path, MAX_PATH);
HINSTANCE res;
res = ShellExecute(NULL, L"runas", Path, Param, NULL, Showcmd);
if ((int)res > 32) return 1;
else return 0;
}
调用时直接 GetWindowsAdmin(); 即可,VS2019 实测可用
调用之后 windows 就会弹出一个窗口,让你确认是否同样给权限。
如果成功了,Windows 会重新创建一个进程来运行你的程序,同时带有管理员权限。
但是与此同时旧的进程并没有关闭,所以你得在调用成功之后关闭程序,不用担心——windows会帮你重新打开这个程序的。
但是这个有个不太好的地方就是调试不方便。因为真正获取到管理员权限在运行的程序是 windows 创建的新进程,旧进程已经关闭了,所以调试比较麻烦,我暂时还不知道怎么调试新进程
我的 Wanna Github 项目用了这个模块,见 https://github.com/zouhuidong/WannaGithub