使用 dotnet new worker -n MyService 创建 Worker Service 项目,需调用 UseWindowsService()、AddWindowsService() 并以 host.Run() 启动,部署时注意管理员权限、路径空格、运行时自包含及日志权限。

直接用 dotnet new worker -n MyService 创建,别碰“Windows Service (.NET Framework)”模板——它在 .NET 6+ 已彻底失效,硬上只会卡在启动失败或事件日志报错 1053。
怎么创建 Worker Service 项目(CLI 和 VS 都行)
Visual Studio 2019+ 或 CLI 均原生支持 Worker Service 模板,无需额外安装插件或拼凑代码。
- 命令行最稳:运行
dotnet new worker -n MyBackgroundService,生成即用 - VS 中新建项目 → 搜索 “Worker Service” → 选 .NET 6/7/8(别选 .NET Framework 版本)
- 不要用 Console App + 手动加
IHostedService:会多出 HTTP 栈、配置冗余,还容易因生命周期错乱导致服务静默退出 - 项目结构固定含
Program.cs和Worker.cs,前者是宿主入口,后者是业务逻辑主干
Worker.cs 里必须用 BackgroundService 而不是裸写 IHostedService
BackgroundService 是微软封装好的基类,已帮你处理了 CancellationToken 传递、线程安全等待和异常传播。手写 IHostedService 极易在 StopAsync 里卡死或漏 await。
- 构造函数只做轻量注入(如
ILogger<Worker>、IConfiguration),别连数据库或开文件 -
ExecuteAsync中必须检查stoppingToken.IsCancellationRequested,不能用while(true) + Thread.Sleep - 延时要用
await Task.Delay(1000, stoppingToken),第二个参数确保能响应停止信号 - 所有耗时操作包进
try/catch,否则未捕获异常会让服务进程直接退出,无日志、无提示
Program.cs 必须调用 UseWindowsService() 并确保 host.Run()
不加 UseWindowsService(),服务注册后无法被 SCM(服务控制管理器)正确识别;不调用 Run(),主线程立刻退出,服务“启动即消失”。
- 需安装 NuGet 包:
Microsoft.Extensions.Hosting.WindowsServices - 在
Program.cs中添加:builder.Services.AddWindowsService(options => options.ServiceName = "MyBackgroundSvc"); - 宿主构建后必须是
host.Run(),不是host.Start()或host.StartAsync()—— 后两者不阻塞主线程 - 发布前确认项目文件含
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" />
部署为 Windows 服务时最常踩的三个坑
90% 的启动失败都集中在这三处:权限、路径、运行时缺失。查事件查看器(Windows Logs → System)里的错误码比猜快得多。
- 注册服务必须用管理员权限运行 cmd,否则
sc create报Access is denied -
sc create的binPath=后面**必须有一个空格**,且路径含空格时得用英文双引号包裹,例如:binPath= "C:\My App\MyService.exe" - 没加
--self-contained true就发布,目标机没装对应 .NET 运行时 → 服务启动失败,事件日志提示0xc0000135 - 日志别写到
C:\Users\...或桌面,服务默认以NT AUTHORITY\SYSTEM运行,那些路径它没权限 —— 改用C:\ProgramData\MyApp\logs\并提前授予权限,或直接写 Windows 事件日志(注册AddEventLog())
真正麻烦的不是写逻辑,而是让服务在系统上下文里“活下来”:它没有控制台、不继承用户会话、权限模型完全不同。每一步注册、发布、路径、日志都要按服务账户视角重想一遍。


















