翻译

Mark Strawmyer 著 Creating a Windows Service in .NET (developer.com)
flanker 翻译 in MSProject

简介

在本文中我们将探讨如何创建一个Windows服务的应用程序。我将说明什么是Windows服务,以及如何创建、安装和调试它。这需要使用System.ServiceProcess.ServiceBase命名空间中的类。

什么是Windows服务?

Windows服务应用程序是在服务器环境中长期运行的应用程序,它没有界面或者可视化的输出,信息一般都写入事件日志中。服务可以在操作系统启动时自动的开始运行,而不需要用户登录来运行它,并且服务可以运行在任何用户的账户中包括system账户。Windows服务通过Service Control Manager(SCM服务控制程序)来管理,控制服务的停止、暂停和重启等。

Windows服务,之前称为NT服务,是在Windows NT操作系统引入的,所以它不适用于Windows 9X或Windows ME系统。要运行Windows服务,你需要NT系列的操作系统,比如Windows NT、Windows 2000等。举几个例子,Microsoft Exchange、SQL Server就是服务器程序的Windows服务,而设置计算机时间的Windows Time是应用程序的Windows服务。

创建一个Windows服务

下面我们创建一个示例,它并没有什么实际用途。当服务启动后,它将在数据库中记录一个表示启动的条目。在它运行期间,每隔特定时长就在数据库中记录一个条目。当它停止时,它会记录一个终止的条目。这个服务也会在启动或者停止成功时,记录在Windows事件日志中。

在Visual Studio .NET中建立Windows服务相对的很简单。下面列出了创建这个示例的步骤:

1. 新建一个项目
2. 在模板中选择Windows服务
3. 设计器将会打开设计模式
4. 从工具箱的组件项里拖拉一个Timer对象到设计器上(注意:使用组件项里的Timer,而不是Windows窗体里的)
flanker注:这里是指需要System.Timers.Timer,而不能使用System.Windows.Forms.Timer。在我的VS2005中,System.Timers.Timer并没有默认出现在工具箱里,需要自己手工添加。)
5. 在Timer属性里将Enabled设置为false,将Interval设置为30000毫秒
6. 切换到代码模式(F7),给服务增加功能

Windows服务的组成

通过代码你会发现Windows服务是继承于System.ServiceProcess.Service类,所有.NET建立的Windows服务都必须继承自这个类。你需要重写以下几个Visual Studio默认提供的方法:

OnStart - 控制服务启动
OnStop - 控制服务终止
Dispose - 清理所有托管和非托管的资源

示例数据库的脚本

下面的T-SQL脚本用来在示例中创建数据库的表。我使用的是SQL Server,你也可以使用Access或者别的选择。

[翻译]使用.NET创建Windows服务CREATE TABLE [dbo].[MyServiceLog] (
[翻译]使用.NET创建Windows服务   
[in_LogId] [int] IDENTITY (11NOT NULL,
[翻译]使用.NET创建Windows服务   
[vc_Status] [nvarchar] (40
[翻译]使用.NET创建Windows服务           COLLATE SQL_Latin1_General_CP1_CI_AS 
NOT NULL,
[翻译]使用.NET创建Windows服务   
[dt_Created] [datetime] NOT NULL
[翻译]使用.NET创建Windows服务
ON [PRIMARY]

示例windows服务

下面是名为MyService的Windows服务示例源代码,代码的大部分都是Visual Studio自动生成的。 

[翻译]使用.NET创建Windows服务using System;
[翻译]使用.NET创建Windows服务
using System.Collections;
[翻译]使用.NET创建Windows服务
using System.ComponentModel;
[翻译]使用.NET创建Windows服务
using System.Data;
[翻译]使用.NET创建Windows服务
using System.Data.SqlClient;
[翻译]使用.NET创建Windows服务
using System.Diagnostics;
[翻译]使用.NET创建Windows服务
using System.ServiceProcess;
[翻译]使用.NET创建Windows服务
[翻译]使用.NET创建Windows服务
namespace CodeGuru.MyWindowsService
}

安装Windows服务

Windows服务有别于其他普通Windows应用程序,不能简单的运行一个EXE文件来启动它。Windows服务应该使用.NET Framework提供的InstallUtil.exe程序来安装,或者通过一个部署项目,比如Microsoft Installer(MSI)文件。

添加安装程序

仅仅创建了Windows服务还不能用InstallUtil程序来安装它。你必须给你的Windows服务添加一个安装程序,这样InstallUtil或者其他的工具才能知道服务的具体配置。

1. 切换到服务的设计模式
2. 右键单击,选择添加安装程序
3. 切换到新增的ProjectInstaller的设计模式
4. 设置serviceInstaller1组件的属性:
    ServiceName = My Sample Service
 StartType = Automatic
5. 设置serviceProcessInstaller1组件的属性:
    Account = LocalSystem
6. 生成解决方案

以上几步完成后,Visual Studio会在ProjectInstalle.cs源文件中自动生成如下的代码。 

[翻译]使用.NET创建Windows服务using System;
[翻译]使用.NET创建Windows服务
using System.Collections;
[翻译]使用.NET创建Windows服务
using System.ComponentModel;
[翻译]使用.NET创建Windows服务
using System.Configuration.Install;
[翻译]使用.NET创建Windows服务
[翻译]使用.NET创建Windows服务
namespace CodeGuru.MyWindowsService

使用InstallUtil安装Windows服务

现在你需要安装你的服务了。按照如下步骤提示,安装你的服务。

1. 打开Visual Studio命令提示
2. 切换到你的项目路径中的bin\Debug目录(如果你用Release模式编译,则进入bin\Release目录)
3. 输入 InstallUtil MyService.exe 来注册你的服务,它将添加所需的注册表信息。
4. 在桌面我的电脑右键选择管理,打开计算机管理
5. 在服务与应用程序中选择服务,你就可以在列表中看到你的服务
6. 右键点击你的服务,选择启动

任何时候你如果需要改变你的Windows服务,你都需要卸载并重新安装它。在卸载服务前,你最后先关闭了服务管理控制台,否则可能在卸载中遇到问题。要卸载服务,只需输入和注册时一样的命令,只不过在后面加上一个/u开关。

调试Windows服务

调试Windows服务比普通应用程序要困难些,需要很多步骤。服务不能像普通应用程序那样在开发环境中直接执行来调试,它必须先安装并启动。一旦启动了它,你可以用Visual Studio附加到进程来调试代码。记住,对Windows服务做的任何改动,你都需要卸载并重新安装它。

附加到运行的Windows服务

要调试服务,你需要按如下步骤附加到Windows服务。这里假设你已经安装了服务并成功启动了它。

1. 在Visual Studio中打开项目
2. 选择调试
3. 选择附加到进程
4. 打开选择所有用户的进程
5. 在可用进程中选择你的进程
6. 点击附加
7. 在timer1_Elapsed方法里设置一个断点,等待它的执行

总结

现在你已经大概了解了什么是Windows服务,以及如何创建、安装和调试它。Windows服务还有许多功能需要你去学习,比如暂停(OnPause)和恢复(OnContinue)等。这几个属性在默认中没有给出,但你可以在属性面板里面设置。

关于作者

Mark Strawmyer, MCSD, MCSE (NT4/W2K), MCDBA 是.NET应用程序高级架构师,服务于大中型组织。Mark是印第安纳波利斯Crowe Chizek公司的技术领导,他关注于架构、设计和开发基于微软技术的解决方案。

附件代码

flanker注:原文并没有附带源代码,因为代码比较简单。这是我自己按照文章做的项目文件。有一点不同:原文输出到数据库,比较麻烦,我这里改用了一个Log类,输出到了文本文件。大家可以看看。
MyService.zip

 

相关文章: