简单的 Windows 服务示例






4.85/5 (379投票s)
2003年4月22日
7分钟阅读

3098041

69371
一个简单的应用程序,展示如何创建 Windows 服务。
引言
实际上,Microsoft Windows 服务(以前称为 NT 服务)允许您创建在自己的 Windows 会话中运行的长期运行的可执行应用程序,这些应用程序可以在计算机启动时自动启动,也可以手动暂停、停止甚至重新启动。
这使得服务非常适合在服务器上使用,或者在需要长期运行的功能而不会干扰同一台计算机上的其他用户时使用。您还可以以不同于登录用户或默认计算机帐户的特定用户帐户的安全上下文中运行服务。
Windows 服务没有任何用户界面,因此无法像普通应用程序那样进行调试,但它是作为进程进行调试的。.NET 提供了一个非常好的工具,可以通过按 Ctrl + Alt + P 快捷键来调试正在运行的进程。
背景
我搜索了很多网站,希望能找到一个可以帮助我构建简单 Windows 服务的代码,但我发现了很多关于如何管理系统当前 Windows 服务(通过 `ServiceController` 类)的代码。
在搜索 MSDN 后,我找到了一些很棒的代码,这些代码帮助我创建了这个简单的 Windows 服务。希望它能作为此类 Windows 服务的基础架构和用法的帮助。
使用代码
首先,您应该简单地打开 VS.NET,然后在“文件”菜单中单击“新建”、“项目”。在“新建项目”对话框中,选择 Windows 服务模板项目,并将名称命名为 `MyNewService`,如下所示。
项目模板会自动添加一个名为 `Service1` 的组件类,该类默认继承自 `System.ServiceProcess.ServiceBase`。
单击设计器。然后在“属性”窗口中,将 `Service1` 的 `ServiceName` 属性设置为 `MyNewService`。
将 `Name` 属性设置为 `MyNewService`。将 `AutoLog` 属性设置为 `true`。
在代码编辑器中,编辑 `Main` 方法以创建 `MyNewService` 的实例。当您在步骤 3 中重命名服务时,`Main` 方法中的类名并未修改。要访问 VC# 中的 `Main` 方法,请展开“组件设计器生成代码”区域。
static void Main()
{
System.ServiceProcess.ServiceBase[] ServicesToRun;
//Change the following line to match.
ServicesToRun = new
System.ServiceProcess.ServiceBase[] { new MyNewService() };
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}
在下一节中,您将为您的 Windows 服务添加自定义事件日志。事件日志与 Windows 服务没有任何关联。这里 `EventLog` 组件用作您可以添加到 Windows 服务的组件类型的示例。
为服务添加自定义事件日志功能
- 在“解决方案资源管理器”中,右键单击 `Service1.vb` 或 `Service1.cs`,然后选择“查看设计器”。
- 从工具箱的“组件”选项卡中,将一个 `EventLog` 组件拖到设计器上。
- 在“解决方案资源管理器”中,右键单击 `Service1.vb` 或 `Service1.cs`,然后选择“查看代码”。
- 编辑构造函数以定义自定义事件日志。
要访问 Visual C# 中的构造函数,请展开“组件设计器生成代码”区域。
public MyNewService()
{
InitializeComponent()
if(!System.Diagnostics.EventLog.SourceExists("DoDyLogSourse"))
System.Diagnostics.EventLog.CreateEventSource("DoDyLogSourse",
"DoDyLog");
eventLog1.Source = "DoDyLogSourse";
// the event log source by which
//the application is registered on the computer
eventLog1.Log = "DoDyLog";
}
要定义服务启动时发生的情况,请在代码编辑器中找到创建项目时自动重写的 `OnStart` 方法,然后编写代码来确定服务开始运行时发生的情况。
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("my service started");
}
一旦服务开始运行,`OnStart` 方法必须返回到操作系统。它不能永远循环或阻塞。要设置简单的轮询机制,您可以使用 `System.Timers.Timer` 组件。在 `OnStart` 方法中,您将设置该组件的参数,然后将 `Timer.Enabled` 属性设置为 `true`。然后,计时器会定期在您的代码中引发事件,此时您的服务就可以进行监控了。
要定义服务停止时发生的情况,请在代码编辑器中找到创建项目时自动重写的 `OnStop` 过程,然后编写代码来确定服务停止时发生的情况。
protected override void OnStop()
{
eventLog1.WriteEntry("my service stoped");
}
您还可以重写 `OnPause`、`OnContinue` 和 `OnShutdown` 方法来为您的组件定义进一步的处理。对于您想要处理的方法,重写适当的方法并定义您想要发生的情况。以下代码显示了如果您重写 `OnContinue` 方法会是什么样子。
protected override void OnContinue()
{
eventLog1.WriteEntry("my service is continuing in working");
}
安装 Windows 服务时需要发生一些自定义操作,这可以通过 `Installer` 类来完成。Visual Studio 可以为 Windows 服务创建这些安装程序,并将它们添加到您的项目中。创建服务的安装程序。
- 返回 `Service1` 的设计视图。
- 单击设计器的背景以选择服务本身,而不是其任何内容。
- 在“属性”窗口中,单击属性列表下方的灰色区域中的“添加安装程序”链接。默认情况下,会向您的项目添加一个包含两个安装程序的组件类。该组件名为 `ProjectInstaller`,它包含的安装程序是您服务的安装程序以及服务关联进程的安装程序。
- 访问 `ProjectInstaller` 的设计视图,然后单击 `ServiceInstaller1`。
- 在“属性”窗口中,将 `ServiceName` 属性设置为 `MyNewService`。
- 将 `StartType` 属性设置为 `Automatic`。
提示
要避免被询问系统用户名和密码,您必须将 `serviceProcessInstaller` 的 `Account` 更改为 `LocalSystem`。这可以通过打开 `ProjectInstaller` 设计,然后选择 `serviceProcessInstaller`,按 `F4`,然后将 `Account` 属性更改为 `LocalSystem` 来完成。或者,您也可以像这样创建一个继承自 `System.Configuration.Install.Installer` 的类来手动完成。
[RunInstaller(true)]
public class ProjectInstaller : System.Configuration.Install.Installer
private System.ServiceProcess.ServiceProcessInstaller
serviceProcessInstaller1;
private System.ServiceProcess.ServiceInstaller serviceInstaller1;
/// <summary>
/// Required designer variable.
/// </summary> private System.ComponentModel.Container components = null;
public ProjectInstaller()
// This call is required by the Designer.
InitializeComponent();
// TODO: Add any initialization after the InitComponent call
}
private void InitializeComponent()
{
this.serviceProcessInstaller1 =
new System.ServiceProcess.ServiceProcessInstaller();
this.serviceInstaller1 =
new System.ServiceProcess.ServiceInstaller();
// serviceProcessInstaller1
//
this.serviceProcessInstaller1.Account =
System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
//
// serviceInstaller1
//
this.serviceInstaller1.ServiceName = "MyNewService";
this.serviceInstaller1.StartType =
System.ServiceProcess.ServiceStartMode.Automatic;
//
// ProjectInstaller
//
this.Installers.AddRange
(new System.Configuration.Install.Installer[]
{
this.serviceInstaller1,
this.serviceInstaller1});
}
}
构建服务项目
- 在“解决方案资源管理器”中,右键单击您的项目,然后从快捷菜单中选择“属性”。将出现项目的“属性页”对话框。
- 在左窗格中,“通用属性”文件夹下的“常规”选项卡。
- 从“启动对象”列表中,选择 `MyNewService`。单击“确定”。
- 按 Ctrl+Shift+B 构建项目。
项目构建完成后,就可以部署了。安装项目将安装编译的项目文件并运行运行 Windows 服务所需的安装程序。要创建完整的安装项目,您需要将项目输出 `MyNewService.exe` 添加到安装项目中,然后添加一个自定义操作以安装 `MyNewService.exe`。
为您的服务创建安装项目
- 在“文件”菜单上,指向“添加项目”,然后选择“新建项目”。
- 在“项目类型”窗格中,选择“设置和部署项目”文件夹。
- 在“模板”窗格中,选择“设置项目”。将项目命名为 `MyServiceSetup`。
将一个设置项目添加到解决方案。接下来,您将把 Windows 服务项目 `MyNewService.exe` 的输出添加到设置中。
将 MyNewService.exe 添加到设置项目
- 在“解决方案资源管理器”中,右键单击 `MyServiceSetup`,指向“添加”,然后选择“项目输出”。将出现“添加项目输出组”对话框。
- `MyNewService` 已在“项目”框中选中。
- 从列表框中选择“主输出”,然后单击“确定”。
将 `MyNewService` 的主输出的项目项添加到设置项目中。现在添加一个自定义操作来安装 `MyNewService.exe` 文件。
向设置项目添加自定义操作
- 在“解决方案资源管理器”中,右键单击设置项目,指向“查看”,然后选择“自定义操作”。将出现“自定义操作”编辑器。
- 在“自定义操作”编辑器中,右键单击“自定义操作”节点,然后选择“添加自定义操作”。将出现“在项目中选择项”对话框。
- 双击列表框中的应用程序文件夹以打开它,选择 `MyNewService` 的主输出(活动),然后单击“确定”。主输出将添加到自定义操作的所有四个节点 — 安装、提交、回滚和卸载。
- 生成安装项目。
安装 Windows 服务
浏览到保存安装项目的目录,然后运行 `.msi` 文件以安装 `MyNewService.exe`。
启动和停止服务
- 通过执行以下操作之一来打开“服务控制管理器”
- 在 Windows 2000 Professional 中,右键单击桌面上的“我的电脑”,然后单击“管理”。在“计算机管理”控制台中,展开“服务和应用程序”节点。
- 或 -
- 在 Windows 2000 Server 中,单击“开始”,指向“程序”,单击“管理工具”,然后单击“服务”。
注意:在 Windows NT 4.0 中,您可以在“控制面板”中打开此对话框。
- 在 Windows 2000 Professional 中,右键单击桌面上的“我的电脑”,然后单击“管理”。在“计算机管理”控制台中,展开“服务和应用程序”节点。
- 现在您应该在窗口的“服务”部分看到列出的 `MyNewService`。
- 在列表中选择您的服务,右键单击它,然后单击“启动”。
右键单击服务,然后单击“停止”。
验证服务的事件日志输出
- 打开“服务器资源管理器”并访问“事件日志”节点。有关更多信息,请参阅“在服务器资源管理器中处理事件日志”。
注意:“服务器资源管理器”的“服务器”节点在 Visual Basic 和 Visual C# .NET 的标准版中不可用。
卸载服务
- 在“开始”菜单上,打开“控制面板”并单击“添加/删除程序”,然后找到您的服务并单击“卸载”。
- 您也可以通过右键单击 `.msi` 文件的程序图标并选择“卸载”来卸载程序。