首页 / C#开发 / 正文

C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案

7058 1 发布于: 2019-04-11 读完约需5分钟

前言

在上一篇文章《在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): 示例源代码下载

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

上一篇: 在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)

下一篇: SQL Server中编写自动生成指定时间段内按小时的连续的数据列表并按每个小时统计数据的SQL语句示例

本文永久链接码友网 » C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案

分享扩散:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册