前言
在上一篇文章《在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)》的最后,我给大家抛出了一个遗留的问题—在将TopshelfDemoService
程序作为Windows服务安装的情况下,由它守护并启动的客户端程序是没有UI界面的。到这里,我们得分析为什么会出现这个问题,为什么在桌面应用程序模式下可以显示UI界面,而在服务模式下没有UI界面?
分析问题(Session 0 隔离)
通过查阅资料,这是由于Session 0 隔离作用的结果。那么什么又是Session 0 隔离呢?
在Windows XP、Windows Server 2003 或早期Windows 系统时代,当第一个用户登录系统后服务和应用程序是在同一个Session 中运行的。这就是Session 0 如下图所示:
但是这种运行方式提高了系统安全风险,因为服务是通过提升了用户权限运行的,而应用程序往往是那些不具备管理员身份的普通用户运行的,其中的危险显而易见。
从Vista 开始Session 0 中只包含系统服务,其他应用程序则通过分离的Session 运行,将服务与应用程序隔离提高系统的安全性。如下图所示:
这样使得Session 0 与其他Session 之间无法进行交互,不能通过服务向桌面用户弹出信息窗口、UI 窗口等信息。这也就是为什么刚才我说那个图已经不能通过当前桌面进行截图了。
潜在的问题
解决方案
在了解了Session 0 隔离之后,给出一些有关创建服务程序以及由服务托管的驱动程序的建议:
1、与应用程序通信时,使用RPC、命名管道等C/S模式代替窗口消息
2、如果服务程序需要UI与用户交互的话,有两种方式:
①用WTSSendMessage来创建一个消息框与用户交互
②使用一个代理(agent)来完成跟用户的交互,服务程序通过CreateProcessAsUser创建代理。
并用RPC或者命名管道等方式跟代理通信,从而完成复杂的界面交互。
3、应该在用户的Session中查询显示属性,如果在Session 0中做这件事,将会得到不正确的结果。
4、明确地使用Local或者Global为命名对象命名,Local/为Session/<n>/BaseNamedObject/,Global/为BaseNamedObject/
5、将程序放在实际环境中测试是最好的方法,如果条件不允许,可以在XP的FUS下测试。在XP的FUS下能工作的服务程序将很可能可以在新版系统中工作,注意XP的FUS下的测试不能检测到在Session 0下跟视频驱动有关的问题
本文我们的服务程序将通过CreateProcessAsUser创建代理来实现Session 0隔离的穿透。
在项目[TopshelfDemoService]中创建一个静态扩展帮助类ProcessExtensions.cs
,代码如下:
修改ProcessHelper.cs
为如下代码:
其中更改了方法
RunProcess()
的调用方式。
重新编译服务程序项目[TopshelfDemoService],并将它作为Windows服务安装,最后启动服务。守护进程服务将启动一个带UI界面的客户端程序。大功告成!!!
我是Rector,希望本文的关于Topshelf服务和守护程序设计对需要的朋友有所帮助。
感谢花你宝贵的时间阅读!!!
参数资料
穿透Session 0 隔离(一)
Windows中Session 0隔离对服务程序和驱动程序的影响
CreateProcessAsUser
源代码下载
本文示例程序源代码托管地址(github): 示例源代码下载
版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。
发表评论
登录用户才能发表评论, 请 登 录 或者 注册