概述:
Windows 服务程序的权限一般只是SYSTEM权限,而UI进程则需要Administrator权限才能正常显示,因此服务进程需要调用UI进程则需要进行提权处理.可使用CreateProcessAsUser 方法创建指定权限的应用程序。
提权则需要获取对应权限令牌,一般explorer.exe进程的权限是Administrator,因此我们可以通过 explorer.exe进程获取Administraror权限。
具体实现方法如下:
//根据进程名称获取进程句柄
HANDLE GetProcessHandle(LPCTSTR szExeName)
{
PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) };
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
if (Process32First(hSnapshot, &Pc)){
do{
if (!_tcsicmp(Pc.szExeFile, szExeName)) {
printf("explorer's PID=%d\n", Pc.th32ProcessID);
return OpenProcess(PROCESS_ALL_ACCESS, TRUE, Pc.th32ProcessID);
}
} while (Process32Next(hSnapshot, &Pc));
}
return NULL;
}
//创建进程阻塞并返回进程句柄
bool ShellExecuteByAdmin( LPCTSTR strCommand, HANDLE* pProcessHandle)
{
HANDLE hToken;
HANDLE hExp = GetProcessHandle(_T("explorer.exe")); //获取进程 句柄
if (hExp == NULL)
return FALSE;
OpenProcessToken(hExp, TOKEN_ALL_ACCESS, &hToken);
if (hToken == NULL)
return FALSE;
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = L"winsta0\\default";
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW;
TCHAR szParameter[256] = {0};
lstrcat(szParameter, strCommand.c_str());
if (CreateProcessAsUser(hToken, NULL, szParameter, NULL,
NULL, FALSE, CREATE_NO_WINDOW|CREATE_NEW_CONSOLE|CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi)) //以administrator用户身份执行程序,CREATE_NO_WINDOW,CREATE_NEW_CONSOLE,CREATE_DEFAULT_ERROR_MODE
{
if (pi.hProcess != INVALID_HANDLE_VALUE)
{
*pProcessHandle = pi.hProcess;
WaitForSingleObject(pi.hProcess, INFINITE); //直到进程结束。可通过pProcessHandle 控制创建进程的生命周期。
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
CloseHandle(hToken);
return 0;
}