引言
Windows服务(Windows Service)是在Windows操作系统后台运行的长期进程,无需用户交互即可执行特定功能。使用C#开发Windows服务程序是许多企业级应用和系统工具的基础。本文将全面介绍如何使用C#开发、安装和管理Windows服务程序。
1. Windows服务基础
1.1 服务程序特点
- 在系统后台自动运行
- 不依赖用户登录状态
- 可以设置为随系统启动而自动运行
- 通过服务控制管理器(SCM)管理
1.2 常见应用场景
- 定时任务执行
- 系统监控
- 数据处理服务
- 网络服务
- 消息队列处理
2. 创建Windows服务项目
2.1 使用Visual Studio创建服务项目
- 新建项目 → Windows服务(.NET Framework)
- 项目会自动生成继承自
ServiceBase
的类
using System.ServiceProcess;
public partial class MyService : ServiceBase
{
public MyService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
// 服务启动逻辑
}
protected override void OnStop()
{
// 服务停止逻辑
}
}
2.2 .NET Core/5+中的服务开发
对于跨平台需求,可以使用Worker Service模板:
dotnet new worker -n MyBackgroundService
或使用Microsoft.Extensions.Hosting
:
using Microsoft.Extensions.Hosting;
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService() // 添加Windows服务支持
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
}
3. 服务核心开发
3.1 主要生命周期方法
protected override void OnStart(string[] args)
{
// 启动服务时执行
// 通常在此初始化资源、启动线程或定时器
}
protected override void OnStop()
{
// 停止服务时执行
// 释放资源、保存状态等
}
protected override void OnPause()
{
// 服务暂停时执行(可选)
}
protected override void OnContinue()
{
// 服务继续时执行(可选)
}
protected override void OnShutdown()
{
// 系统关闭时执行(可选)
}
3.2 添加服务功能
定时任务实现
private Timer _timer;
protected override void OnStart(string[] args)
{
_timer = new Timer(DoWork, null, TimeSpan.Zero,
TimeSpan.FromMinutes(30));
}
private void DoWork(object state)
{
// 定期执行的任务逻辑
EventLog.WriteEntry("服务执行了定期任务", EventLogEntryType.Information);
}
protected override void OnStop()
{
_timer?.Dispose();
}
事件日志记录
// 在构造函数中初始化事件日志
public MyService()
{
InitializeComponent();
if (!EventLog.SourceExists("MyServiceSource"))
{
EventLog.CreateEventSource("MyServiceSource", "MyServiceLog");
}
EventLog.Source = "MyServiceSource";
EventLog.Log = "MyServiceLog";
}
// 记录信息
EventLog.WriteEntry("服务启动成功", EventLogEntryType.Information);
4. 服务安装与部署
4.1 添加安装程序
- 在设计视图右键点击 → 添加安装程序
- 会自动生成
ProjectInstaller
类和两个组件:
serviceProcessInstaller1
– 设置运行账户serviceInstaller1
– 设置服务属性
[RunInstaller(true)]
public partial class ProjectInstaller : Installer
{
public ProjectInstaller()
{
InitializeComponent();
// 设置服务运行账户
serviceProcessInstaller1.Account = ServiceAccount.LocalSystem;
// 设置服务属性
serviceInstaller1.ServiceName = "MyService";
serviceInstaller1.DisplayName = "我的自定义服务";
serviceInstaller1.Description = "这是一个示例Windows服务";
serviceInstaller1.StartType = ServiceStartMode.Automatic;
}
}
4.2 安装和卸载服务
使用InstallUtil.exe安装
# 安装
InstallUtil.exe MyService.exe
# 卸载
InstallUtil.exe /u MyService.exe
使用SC命令安装
sc create MyService binPath= "C:\path\to\MyService.exe" start= auto
sc description MyService "我的自定义服务"
sc start MyService
# 卸载
sc delete MyService
以编程方式安装
using System.Configuration.Install;
using System.ServiceProcess;
public static void InstallService(string exePath)
{
ManagedInstallerClass.InstallHelper(new[] { exePath });
}
public static void UninstallService(string exePath)
{
ManagedInstallerClass.InstallHelper(new[] { "/u", exePath });
}
5. 服务调试技巧
5.1 调试模式运行
修改Program.cs
以支持调试模式:
static class Program
{
static void Main()
{
if (Environment.UserInteractive)
{
// 调试模式运行
var service = new MyService();
service.OnDebugStart();
Console.WriteLine("服务在调试模式下运行,按任意键停止...");
Console.ReadKey();
service.OnDebugStop();
}
else
{
// 正常服务模式运行
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new MyService() };
ServiceBase.Run(ServicesToRun);
}
}
}
// 在服务类中添加调试方法
public partial class MyService : ServiceBase
{
public void OnDebugStart()
{
OnStart(null);
}
public void OnDebugStop()
{
OnStop();
}
}
5.2 附加到进程调试
- 安装并启动服务
- Visual Studio → 调试 → 附加到进程
- 选择服务进程(通常与项目同名)
- 设置断点进行调试
6. 高级主题
6.1 服务恢复选项
配置服务崩溃后自动重启:
// 在ProjectInstaller中
serviceInstaller1.ServicesDependedOn = new[] { "SomeDependentService" };
// 通过SC命令设置恢复选项
sc failure MyService reset= 60 actions= restart/60000/restart/60000/run/1000
6.2 多服务应用程序
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun = new ServiceBase[]
{
new Service1(),
new Service2(),
new Service3()
};
ServiceBase.Run(ServicesToRun);
}
}
6.3 与WCF集成
创建WCF服务宿主:
protected override void OnStart(string[] args)
{
_serviceHost = new ServiceHost(typeof(MyWcfService));
_serviceHost.Open();
}
protected override void OnStop()
{
_serviceHost?.Close();
}
7. 最佳实践
- 异常处理:服务中所有代码都应包含try-catch块,防止服务意外停止
- 资源管理:确保正确释放所有资源(文件句柄、网络连接等)
- 性能考虑:避免在服务中使用过多内存或CPU资源
- 日志记录:实现详细的日志记录,便于故障排查
- 配置管理:使用配置文件(app.config)存储服务参数
- 版本控制:实现服务版本检查机制
结语
C# Windows服务开发是构建可靠后台应用程序的强大工具。通过合理设计服务架构、实现完善的错误处理和日志记录,可以创建出稳定高效的系统服务。对于现代开发,考虑使用Worker Service模式可以更好地支持跨平台场景。无论选择哪种方式,理解服务生命周期、掌握调试技巧和遵循最佳实践都是开发高质量服务程序的关键。