Windows Service 项目模板在哪?VS 2022 还有吗
Visual Studio 2022 默认已移除「Windows Service (.NET Framework)」项目模板,.NET Core / .NET 5+ 也不再原生支持传统
ServiceBase托管方式。想用 C# 写 Windows 服务,现在主流路径是:.NET 6+ +
WorkerService模板 +
Microsoft.Extensions.Hosting.WindowsServices包。
新建项目时选「Worker Service」,不是「Console App」——虽然底层都是控制台宿主,但
WorkerService自带
IHostedService基础结构,更贴近服务生命周期管理。 若必须兼容旧版(如需安装到 Windows Server 2008 或依赖
ServiceController直接通信),只能用 .NET Framework 4.7.2+ +
ServiceBase,且需手动创建项目、添加引用 .NET 6+ 的
WorkerService在 Windows 上可注册为服务,但不支持交互式桌面会话(
AllowServiceToInteractWithDesktop已废弃) 安装工具统一用
sc.exe或 PowerShell
New-Service,不再依赖
InstallUtil.exe(它在 .NET Core+ 中不可用)
如何让 WorkerService 正确注册为 Windows 服务
核心是两步:修改宿主配置 + 添加 Windows 服务支持包。缺一不可,否则
sc start会报错 1053(服务未及时响应启动或控制请求)。
先安装 NuGet 包:
dotnet add package Microsoft.Extensions.Hosting.WindowsServices
然后在
Program.cs中启用 Windows 服务支持:
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<MyBackgroundService>();
// 必须加这行,否则无法作为服务运行
builder.Services.AddWindowsService(options =>
{
options.ServiceName = "MyAppWorkerService";
});
var host = builder.Build();
host.Run();
options.ServiceName必须设置,且不能含空格或特殊字符(建议纯字母数字) 不要调用
host.Start()后再
host.WaitForShutdown()——
host.Run()已封装完整服务生命周期 发布时用
dotnet publish -c Release -r win-x64 --self-contained true,生成独立部署包,避免目标机缺少运行时
服务启动失败常见错误和排查点
最常遇到的是事件查看器里显示「服务没有及时响应启动或控制请求」(错误 1053),本质是宿主初始化卡住或未正确绑定 Windows 服务上下文。
检查是否漏掉AddWindowsService()调用 —— 这是最常见疏漏,会导致
Environment.UserInteractive仍为
true,服务进程误判为控制台模式 确认程序入口点(
Main方法)是否直接调用
host.Run();若用了
await host.RunAsync()但没设
async Main,会编译失败 日志输出默认不写入 Windows 事件日志,需显式添加
builder.Logging.AddEventLog()并配置
SourceName服务账户权限不足(比如用 LocalSystem 以外的账户运行,又试图访问网络路径或注册表)—— 临时调试可先设为
LocalSystem,上线再降权
如何安装、启动、卸载服务(命令行实操)
全部使用管理员权限的 PowerShell 或 CMD,别用普通用户窗口。
安装(假设发布后路径为
C:\MyApp\MyApp.exe):
sc create MyAppService binPath= "C:\MyApp\MyApp.exe" start= auto obj= "LocalSystem"
注意:
binPath=后面有空格,
start=和
obj=同理;路径含空格必须用英文双引号包裹整个路径值,而不是只包路径。
启动与验证:
sc start MyAppService sc query MyAppService
卸载前务必先停止:
sc stop MyAppService sc delete MyAppService
sc query看
STATE是否为
RUNNING,
WIN32_EXIT_CODE是否为
0x0如果服务一闪而退,立刻查 Windows 事件查看器 → Windows 日志 → 应用程序,筛选来源为你的
SourceName或
.NET Runtime开发阶段可先以控制台模式运行(不注册服务):直接双击 exe 或
dotnet MyApp.dll,方便调试日志和异常堆栈
.NET 6+ 的 Windows 服务模型绕过了
ServiceBase,但生命周期钩子(如启动/停止通知)得靠
IHostedService.StartAsync()/StopAsync()实现;很多人卡在「服务装上了却没执行业务逻辑」,往往是因为忘了在
StartAsync里真正启动后台任务(比如
Task.Run或定时器),或者异常没捕获导致
StartAsync提前退出。
