欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > VC++ 服务守护qt用户级UI进程

VC++ 服务守护qt用户级UI进程

2025/12/13 14:20:08 来源:https://blog.csdn.net/yanchenyu365/article/details/148793210  浏览:    关键词:VC++ 服务守护qt用户级UI进程

适合用于本地服务程序(以 WinMainServiceMain 模式运行)

一、示例 

#include <windows.h>
#include <userenv.h>
#include <wtsapi32.h>
#include <tlhelp32.h>
#include <string>
#include <vector>
#include <thread>#pragma comment(lib, "Wtsapi32.lib")
#pragma comment(lib, "Userenv.lib")bool IsProcessRunning(const std::wstring& exeName) {PROCESSENTRY32 pe = { sizeof(pe) };HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (snap == INVALID_HANDLE_VALUE) return false;bool found = false;if (Process32First(snap, &pe)) {do {if (_wcsicmp(pe.szExeFile, (exeName + L".exe").c_str()) == 0) {found = true; break;}} while (Process32Next(snap, &pe));}CloseHandle(snap);return found;
}void LaunchAsActiveUser(const std::wstring& fullPath) {DWORD sessionId = WTSGetActiveConsoleSessionId();HANDLE userToken = NULL, primaryToken = NULL;if (!WTSQueryUserToken(sessionId, &userToken)) return;if (!DuplicateTokenEx(userToken, MAXIMUM_ALLOWED, NULL,SecurityImpersonation, TokenPrimary, &primaryToken)) return;LPVOID env = nullptr;CreateEnvironmentBlock(&env, primaryToken, FALSE);STARTUPINFOW si = { sizeof(si) };si.lpDesktop = const_cast<LPWSTR>(L"winsta0\\default");PROCESS_INFORMATION pi = {};CreateProcessAsUserW(primaryToken, NULL, const_cast<LPWSTR>(fullPath.c_str()),NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT,env, NULL, &si, &pi);if (pi.hProcess) CloseHandle(pi.hProcess);if (pi.hThread) CloseHandle(pi.hThread);if (env) DestroyEnvironmentBlock(env);CloseHandle(userToken);CloseHandle(primaryToken);
}void ProtectUserProcesses(const std::vector<std::wstring>& names, const std::wstring& folder) {std::thread([=]() {while (true) {for (auto& name : names) {if (!IsProcessRunning(name)) {OSVERSIONINFO vi = { sizeof(vi) };GetVersionEx(&vi);std::wstring exePath = folder + L"\\" + name + L".exe";if (vi.dwMajorVersion <= 5) {LaunchProcessAsCurrentUserXP(exePath,folder)} else {LaunchAsActiveUser(exePath);}}}Sleep(5000);}}).detach();
}bool LaunchProcessAsCurrentUserXP(const std::wstring& applicationPath, const std::wstring& workingDirectory)
{HANDLE hToken = NULL;HANDLE hTokenDup = NULL;bool success = false;// 获取当前活动 Session IDDWORD sessionId = WTSGetActiveConsoleSessionId();// 遍历进程,寻找 explorer.exe(登录用户拥有的进程)HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hSnapshot == INVALID_HANDLE_VALUE)return false;PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) };if (Process32First(hSnapshot, &pe32)) {do {if (_wcsicmp(pe32.szExeFile, L"explorer.exe") == 0) {// 打开 explorer.exe 进程HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);if (hProcess) {if (OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) {CloseHandle(hProcess);break; // 找到 token 就退出}CloseHandle(hProcess);}}} while (Process32Next(hSnapshot, &pe32));}CloseHandle(hSnapshot);if (!hToken)return false;// 复制 tokenif (!DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, &hTokenDup)) {CloseHandle(hToken);return false;}// 启动信息STARTUPINFO si = { sizeof(STARTUPINFO) };PROCESS_INFORMATION pi = { 0 };si.lpDesktop = const_cast<LPWSTR>(L"winsta0\\default");// 创建进程(使用用户权限)success = CreateProcessAsUserW(hTokenDup,applicationPath.c_str(),NULL,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,workingDirectory.c_str(),&si,&pi) == TRUE;if (success) {CloseHandle(pi.hThread);CloseHandle(pi.hProcess);}CloseHandle(hToken);CloseHandle(hTokenDup);return success;
}

二、使用

// C++
ProtectUserProcesses({ L"MyTrayApp", L"UserAgent" }, L"C:\\Program Files\\MyApp"); 

三、注意

在 Windows XP SP3 环境中,当通过 ShellExecute 从服务进程启动新进程时,该进程会继承服务进程的 SYSTEM 权限。由于大多数 UI 进程需要用户级权限,就需要降权处理。然而 Windows XP 不支持 WTSQueryUserToken 函数(该功能仅适用于 Windows Server 2003 及更高版本),因此解决方案是获取 explorer.exe 的 Token 来启动 UI 进程

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词