通过Windows系统服务守护进程的运行
遇到这样一个需求,需要保持一个桌面客户端程序在用户电脑上的运行,并在意外关闭或者手动关闭后也要重新启动
初步尝试
在平时的开发过程中,遇到需要启动进程的需求,肯定会想到使用:
1
System.Diagnostics.Process.Start("Example.exe");
这样的方式来启动一个进程,于是针对现在的需求,我们可能会在系统服务程序中写这样的代码:
1
2
3
4
5
6
7
8
9
10
11
var processName = "notepad";
while (true)
{
Thread.Sleep(5000);
if (!(Process.GetProcessesByName("notepad")?.Length > 0))
{
Process.Start(processName);
}
}
为了验证是否能够生效,我们安装系统服务并启动这个系统服务1
等待了一段时间,在操作系统界面上,没有看到记事本程序像预期那样启动。通常可能会认为进程没有被正常的启动,或者代码执行过程中出现了什么问题,但是当我们使用任务管理器等方式查找进程,却发现名字为notepad的进程已经存在了,这是怎么回事呢?
探索原因
在一番搜索之后,终于发现了原因(具体可以查看本文下方中获取到这些知识的文章)。原来从Windows Vista开始,Windows系统引入了Session 0 隔离机制,这个机制是出于一些安全方面的考量
In Windows XP, Windows Server 2003, and earlier versions of the Windows operating system, all services run in the same session as the first user who logs on to the console. This session is called Session 0. Running services and user applications together in Session 0 poses a security risk because services run at elevated privilege and therefore are targets for malicious agents who are looking for a means to elevate their own privilege level.
首先要明白Windows系统中Session的概念,在Windows系统中,每个登录的用户都会被分配到一个唯一的SessionId,每个Session之间是彼此有隔离的,按照目前对于Session的理解,可以认为:
进程是为了内部的执行的线程提供一个空间和环境,而会话则是为内部所有的进程提供一个执行的空间和环境。
在早期的Windows系统中,Windows服务进程与第一个登录进入系统的用户共享同一个Session,没有做任何隔离,这样会引发一些隐患,比如恶意软件可以通过与Windows服务进程进行通讯,来造成一些超出用户权限能力的破坏
于是,由于Windows服务被隔离到了一个单独的Session,也就是Session 0,所以当我们通过Windows服务启动进程的时候,这个进程是在Session 0中被启动,我们无法看到其交互界面
解决问题
按照参考文章中的说法,想要从Session 0产生一些具有交互界面的行为,可以使用调用Win32 Api来实现:
- 可以使用
WTSSendMessage
往用户桌面创建一个简单的消息框 - 使用
CreateProcessAsUser
函数在用户会话中创建进程
很明显,第二个选项就是我们需要的,于是我们在代码中调用这个函数,即可解决这个问题,详见代码[ProcessGuard/ApplicationLoader.cs at main · GadHao/ProcessGuard (github.com)]里的StartProcessInSession0()
函数,代码中有详细注释
开发工具
利用上面介绍的方法开发了进程守护服务,并且制作了WPF界面管理整个守护服务从安装使用到停止和卸载的整个过程,有兴趣或者有需要的可以下载使用:
Releases · GadHao/ProcessGuard (github.com)
参考内容
本文,特别是文中的引用部分参考了这些文章的内容:
Subverting Vista UAC in Both 32 and 64 bit Architectures By Pero Matić
Application Compatibility - Session 0 Isolation By Craig Marcho
关于如何安装和启动系统服务,可以查看Windows相关备忘的第18到20点 ↩