我们已用户权限运行程序,有时候需要在指定的路径下修改文件,而因为没有管理员权限导致失败。此时,我们可以使用管理员权限运行一个新的进程,用这个新的进程来执行修改任务。
判断是否具有管理员权限
//判断管理员权限
bool IsAdmin()
{
BOOL b;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);
if (b)
{
if (!CheckTokenMembership(NULL, AdministratorsGroup, &b))
{
b = FALSE;
}
FreeSid(AdministratorsGroup);
}
return(b);
}
判断系统版本是否是win7以上
bool IsAboveVistaVersion() //判断系统版本是否是win7以上
{
OSVERSIONINFOEX WinVersion;
ZeroMemory(&WinVersion, sizeof(OSVERSIONINFOEX));
WinVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
BOOL flag = (BOOL)GetVersionEx((OSVERSIONINFO *)&WinVersion);
assert(flag);
if (WinVersion.dwMajorVersion < 6)
return false;
if (WinVersion.dwMajorVersion == 6 && WinVersion.dwMinorVersion == 1)
return false;
if (WinVersion.dwMajorVersion == 6 && WinVersion.dwMinorVersion >= 2)
return true;
if (WinVersion.dwMajorVersion > 6)
return true;
return true;
}
以管理员运行程序:
wstring GetExePath()
{
WCHAR buf[MAX_PATH] = { 0 };
wstring strPath;
GetModuleFileName(nullptr, buf, MAX_PATH);
strPath = buf;
return strPath;
}
//是否初次运行
bool IsFirstRun(string sFileName, string sAppName, string sKeyName)
{
bool bRet = false;
char cModulePath[MAX_PATH] = { 0 };
GetModuleFileNameA(NULL, cModulePath, MAX_PATH);
PathRemoveFileSpecA(cModulePath);
string strPath = cModulePath;
strPath += "\\" + sFileName;
int nIndex = GetPrivateProfileIntA(sAppName.c_str(), sKeyName.c_str(), 0, strPath.c_str());
if (nIndex == 0)
{
bRet = true;
WritePrivateProfileStringA(sAppName.c_str(), sKeyName.c_str(), "1", strPath.c_str());
}
if (!IsAdmin() && IsAboveVistaVersion())
{
wstring exePath(GetExePath());
SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.lpVerb = L"runas";
sei.lpFile = exePath.c_str();
sei.lpParameters = L"FirstRun";
if (!ShellExecuteEx(&sei))
{
DWORD dwStatus = GetLastError();
if (dwStatus == ERROR_CANCELLED)
{
//debug_showmessage("提升权限出错\n");
}
}
}
return bRet;
}
此时使用管理员权限开启一个进程,并带有一个参数“FirstRun”
wstring strCmd = szArglist[1];
if (strCmd == L"FirstRun")//第一次运行时调用
{
SetFirstRun("set.ini","Install","FirstRun");
return 0;
}
在该进程main函数中,判断参数是否为“FirstRun”,如果是则执行需要管理员权限的代码