在 .NET 中使用控制台模式的简单 Windows 服务






4.27/5 (6投票s)
一个用于实现简单 Windows 服务的框架,侧重于可用性。
引言
Windows 服务是很有用的东西。不幸的是,微软并没有简化编写自己的服务的过程。更重要的是,它们在开发期间可能很难调试。
本文介绍了一个用于创建您自己的 Windows 服务的简单框架。它接受几个命令行参数,使安装、启动、停止和卸载服务变得轻而易举。此外,它还具有控制台模式,使调试变得容易。
背景
我花了很多时间浏览了大量的页面和站点,寻找用于开发 Windows 服务的示例代码。现有的示例并没有真正做到我想要的一切。有些使用了相当大的技巧,而且没有一个将服务部分与实际的工作者部分分开。这个项目包含了我认为对于一个可用的 Windows 服务而言的最低限度的功能,以及一个用于添加您的工作者代码的简单接口。
Using the Code
这是为 Visual Studio 2008 和 .NET 3.5 设定的。要将此代码用于 .NET 2.0,需要进行一些修改,例如,摆脱 lambda 函数,但这很容易做到。
ISimpleServiceWorker
您只需继承 ISimpleServiceWorker
接口并在您的工作者类中实现它。
using System;
namespace RPW.Simple
{
interface ISimpleServiceWorker
{
void Init();
void Run();
void Cleanup();
}
}
在 Init()
方法中初始化您的资源,并在 Cleanup()
方法中清理您的资源。 Run()
方法通常包含一个循环,用于管理您的任务的状态。 您不必创建线程; SimpleProject
类将创建必要的线程。 您应该记住,线程将由 Thread.Abort()
方法终止。 ThreadAbortException
将在创建线程上下文的 SimpleProject
类中被捕获,因此您无需捕获它,但如果出于某种原因,您可以捕获它。 为了保持合理的关闭时间,尽量不要进行阻塞调用,例如套接字。
控制台模式
服务众所周知很难调试。 因此,此项目提供了一个控制台模式,以便您可以在没有所有服务开销的情况下运行您的代码。 只需将 -console 命令行开关传递给您的服务可执行文件,Shazaam! 您正在以控制台模式运行。 在控制台模式下,SimpleService
类的静态 WriteLog
方法会将日志记录定向到控制台窗口,而不是应用程序事件日志。
管理您的服务
SimpleService
类提供了几个命令行开关
PS C:\rev\src\simpleservice\src\bin\release> .\SimpleService.exe -help
= usage:
= SimpleService -install == install service
= SimpleService -uninstall == uninstall service
= SimpleService -start == start service
= SimpleService -stop == stop service
= SimpleService -status == get the current status of the service
= SimpleService -console == run in console mode
= SimpleService -help == show this help message
PS C:\rev\src\simpleservice\src\bin\release>
使用这些命令行开关,您可以在不使用 InstallUtil.exe 的情况下安装和卸载您的服务。 此外,您可以在安装服务后启动和停止它。 -status 开关将告诉您您的服务是否已安装、启动或停止。
细微差别
该项目使用进程名称作为服务名称。 您可以在代码中更改此设置,但您必须确保将相同的名称应用于 ServiceBase
和 ServiceInstaller
。 为了简单起见,请使用 SimpleServiceInstaller
类的静态 ServiceName
属性。
该项目假定您的服务需要 LocalSystem 权限并自动启动。 当您使用该服务时,这将调用 Windows Vista 和 Windows 7 UAC 对话框。 您可以在 SimpleServiceInstaller
类中更改这些默认设置。
public SimpleServiceInstaller()
{
// setup and add the process installer
m_processInstaller = new ServiceProcessInstaller()
{
Account = ServiceAccount.LocalSystem
};
Installers.Add(m_processInstaller);
// setup and add the service installer
m_serviceInstaller = new ServiceInstaller()
{
StartType = ServiceStartMode.Automatic,
// ServiceName must equal those on ServiceBase derived classes.
ServiceName = ServiceName,
DisplayName = ServiceName,
Description = ServicePath
};
Installers.Add(m_serviceInstaller);
}
结论
我想您会对这个设计感到满意。 只需通过继承 ISimpleServiceWorker
接口来实现一个工作者类,更改项目程序集名称并构建它! 命令行开关使一切变得轻而易举。 请随时通知我错误或疏忽。 当然,尽情享受吧!
历史
- 2010 年 1 月 - 初始提交。