windows c++ (8) 守护服务守护带界面的进程遇到的问题

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。

相关推荐
gis收藏家6 分钟前
利用 SAM2 模型探测卫星图像中的农田边界
开发语言·python
Ciderw9 分钟前
MySQL为什么使用B+树?B+树和B树的区别
c++·后端·b树·mysql·面试·golang·b+树
yerennuo15 分钟前
windows第七章 MFC类CWinApp介绍
c++·windows·mfc
齐雅彤17 分钟前
Bash语言的并发编程
开发语言·后端·golang
AitTech26 分钟前
C#性能优化技巧:利用Lazy<T>实现集合元素的延迟加载
开发语言·windows·c#
翻晒时光26 分钟前
深入解析Java集合框架:春招面试要点
java·开发语言·面试
峰子201232 分钟前
B站评论系统的多级存储架构
开发语言·数据库·分布式·后端·golang·tidb
爱辉弟啦37 分钟前
Windows FileZila Server共享电脑文件夹 映射21端口外网连接
linux·windows·mac·共享电脑文件夹
ExRoc1 小时前
蓝桥杯真题 - 填充 - 题解
c++·算法·蓝桥杯
Channing Lewis1 小时前
python如何使得pdf加水印后的大小尽可能小
开发语言·python·pdf