1、问题
在维护守护服务时,现场需要守护一个带界面的进程。将进程路径加入守护目录后,现场人员主动关闭界面验证守护功能,发现进程被拉起,但是进程的界面没有显示。
2、现场环境
windows 7
3、处理方法
1 使用 CreateProcessAsUser 以用户身份启动进程
cpp
#include <windows.h>
#include <iostream>
void StartGUIApplication() {
const wchar_t* guiAppPath = L"C:\\Path\\To\\Your\\MFCApplication.exe";
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE hToken;
HANDLE hTokenDup;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
ZeroMemory(&pi, sizeof(pi));
// 打开一个你知道是GUI用户的token 不能用 GetCurrentProcess() 着个用户是system
if (!OpenProcessToken("YouKownGui.exe", TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &hToken)) {
std::cerr << "OpenProcessToken failed (" << GetLastError() << ").\n";
return;
}
// Duplicate the token
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hTokenDup)) {
std::cerr << "DuplicateTokenEx failed (" << GetLastError() << ").\n";
CloseHandle(hToken);
return;
}
// Create the process as the user
if (!CreateProcessAsUser(hTokenDup, NULL, (LPWSTR)guiAppPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
std::cerr << "CreateProcessAsUser failed (" << GetLastError() << ").\n";
}
CloseHandle(hTokenDup);
CloseHandle(hToken);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
dart
注:你得知道且确认一个你已知的在用户会话中运行的程序(YouKownGui.exe)
2 将守护服务以控制台模式运行
为确保守护不会被误操作关闭,隐藏控制台,并在系统任务计划内添加定时检测守护是否存在的定时任务。
1 编写一个powershell脚本来检查守护是否运行
以下是一个简单的 PowerShell 脚本示例(Check.ps1):
bash
# 定义要检查的进程名(不需要扩展名)
$processName = "YourProcessName"
$executablePath = "C:\Path\To\YourExecutable.exe"
# 获取进程列表
$processes = Get-Process -Name $processName -ErrorAction SilentlyContinue
if ($processes) {
Write-Output "进程 '$processName' 正在运行."
} else {
Write-Output "进程 '$processName' 没有运行."
# 启动进程
Start-Process -FilePath $executablePath
}
2. 创建任务计划
使用任务计划程序创建一个任务来定期运行这个脚本。
- 打开任务计划程序(在开始菜单中搜索"任务计划程序")。
- 选择"创建基本任务"。
- 输入任务的名称和描述,点击"下一步"。
- 选择任务触发器,例如"每天"或"每次计算机启动时",点击"下一步"。
- 设置触发器的具体时间或频率,点击"下一步"。
- 选择"启动程序",点击"下一步"。
- 在"程序/脚本"框中输入 powershell.exe。
- 在"添加参数"框中输入 -File "C:\Path\To\Check.ps1"。
- 点击"下一步",然后点击"完成"。
4、原因
交互式用户会话:GUI 程序通常需要在用户会话中运行 。服务默认以 LocalSystem 身份运行,无法直接显示 GUI。