Windows服务设计与实现

在Windows操作系统中,服务是一种在后台运行的程序,它不提供用户界面,通常用于执行系统级任务。然而,Visual Studio提供的Windows服务模板存在一些不便,例如生成的代码不能作为控制台应用程序运行,这给调试带来了不便。此外,开发者通常需要实现比Visual Studio模板提供的更适当的线程模型。本文将介绍一种设计方法,解决这些问题,并提供代码示例。

Windows服务通常与系统托盘中的图标配合使用,以便用户可以监控服务状态并进行控制。由于Windows服务没有可视化界面,因此需要另一个应用程序来确保在系统托盘中正确显示服务的当前状态。在示例中,这个额外的应用程序是用WPF编写的。通常,这个“托盘目标”应用程序与Windows服务在同一台机器上运行。因此,双工WCF与IPC(net.pipe)绑定似乎是两个进程之间通信的自然选择,其中Windows服务充当服务器。

设计

示例Windows服务“SampleWinService”具有以下特点:

  • 能够作为控制台应用程序或Windows服务运行。
  • 作为Windows服务使用时,支持自安装和自卸载。
  • 作为“有用”客户端和WPF托盘目标应用程序的服务器,通过托管WCF双工服务对象。
  • 提供基于命令的工作范式,客户端应用程序通过WCF通信发送命令。命令由WCF服务对象排队到命令队列中。命令由专用工作线程循环处理。处理结果发送给调用的有用客户端(如果需要),而当前Windows服务状态发送给WPF托盘目标应用程序。结果和状态都使用WCF双工机制作为回调发送。

在示例中,外部应用程序提供命令,使服务执行有用的工作。在现实生活中,也可以有其他有用的命令来源,例如硬件输入、驱动程序、计时器等。

“SampleWinService”设计基于以下合理假设:

  • 托盘目标GUI应用程序与服务在同一台机器上运行。
  • Windows服务的客户数量有限。
  • 服务和所有客户之间没有防火墙。

第一个假设允许托盘目标应用程序使用由System.Management.ManagementEventWatcher类提供的异步通知,以获取服务状态更改。第二和第三个假设证明了使用双工WCF服务的合理性。当然,上述假设并非强制性的,只是为了简单起见。将在本文的讨论部分简要回顾其他情况。

代码示例

在示例中,Windows服务由SimpleWinService项目表示,IconClient和TestClient项目分别代表图标目标和有用客户端。

// 以下是一个简单的代码示例,展示了如何创建一个Windows服务 using System.ServiceProcess; using System.ComponentModel; public class SampleWinService : ServiceBase { public SampleWinService() { this.ServiceName = "SampleWinService"; } protected override void OnStart(string[] args) { // 在这里添加服务启动时的代码 } protected override void OnStop() { // 在这里添加服务停止时的代码 } }

演示

要运行演示,需要对SimpleWinService Windows服务进行自注册。为此,运行SimpleWinService_Install.cmd文件(该文件使用/install参数启动SimpleWinService.exe)。然后启动IconClient.exe,并使用托盘图标及其弹出菜单来控制SimpleWinService Windows服务并观察其状态。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485