在Windows操作系统中,服务是一种在后台运行的程序,它不提供用户界面,通常用于执行系统级任务。然而,Visual Studio提供的Windows服务模板存在一些不便,例如生成的代码不能作为控制台应用程序运行,这给调试带来了不便。此外,开发者通常需要实现比Visual Studio模板提供的更适当的线程模型。本文将介绍一种设计方法,解决这些问题,并提供代码示例。
Windows服务通常与系统托盘中的图标配合使用,以便用户可以监控服务状态并进行控制。由于Windows服务没有可视化界面,因此需要另一个应用程序来确保在系统托盘中正确显示服务的当前状态。在示例中,这个额外的应用程序是用WPF编写的。通常,这个“托盘目标”应用程序与Windows服务在同一台机器上运行。因此,双工WCF与IPC(net.pipe)绑定似乎是两个进程之间通信的自然选择,其中Windows服务充当服务器。
示例Windows服务“SampleWinService”具有以下特点:
在示例中,外部应用程序提供命令,使服务执行有用的工作。在现实生活中,也可以有其他有用的命令来源,例如硬件输入、驱动程序、计时器等。
“SampleWinService”设计基于以下合理假设:
第一个假设允许托盘目标应用程序使用由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服务并观察其状态。