windows服务onstart必须在30秒内返回,禁止同步阻塞;.net6+禁用installutil,改用sc.exe安装;调试需debugger.launch()或条件编译;路径用appcontext.basedirectory,日志优先验证eventlog。

Windows 服务在 C# 中根本不是“写完 OnStart 就能跑”的控制台程序——OnStart 超过 30 秒不返回,必然触发错误 1053;用 InstallUtil.exe 安装 .NET 6+ 项目会静默失败;直接双击 exe 或 Ctrl+F5 调试,OnStart 根本不会执行。
OnStart 里写了 Thread.Sleep 或 HttpClient.GetAsync 就会报错 1053
错误 1053 的本质是 Windows SCM(服务控制管理器)在约 30 秒内没收到 OnStart 的返回信号,直接判定启动失败。很多人把数据库连接、配置加载、HTTP 请求、文件扫描全塞进 OnStart,结果服务卡在“正在启动”状态,日志里连第一行都看不到。
- 必须把耗时逻辑移出
OnStart:只留轻量初始化,比如创建Timer、启动Task.Run(() => { ... })、或注册BackgroundService - 禁止出现任何同步阻塞调用:
Thread.Sleep、File.ReadAllText(未加超时)、HttpClient.Send等一律删掉或改异步 -
async void OnStart是危险陷阱:SCM 不 await 它,线程可能被回收,逻辑实际没执行完就退出 - 第一行日志务必用
EventLog.WriteEntry,别用Console.WriteLine(服务无控制台)
.NET 6+ 项目别碰 InstallUtil.exe
InstallUtil.exe 是 .NET Framework 工具,.NET Core / .NET 5+ 默认不带它,硬拷老版本会导致注册表项缺失、服务无法启动,且不兼容现代宿主模型。
- 推荐安装方式:PowerShell +
sc.exe,与 SDK 版本无关sc create "MyService" binPath= "C:\MyApp\MyService.exe" start= auto obj= ".\LocalSystem" - 注意空格:
binPath=和start=后必须各有一个空格;路径含空格需英文双引号包裹 - 安装后立刻测试:
sc start "MyService",别等 services.msc 刷新 - 卸载用
sc delete "MyService",不是InstallUtil /u
调试时断点不命中?因为你根本没走服务流程
右键项目 → “调试 → 开始执行(不调试)” 或双击 exe,只是普通进程启动,OnStart 压根不会被调用——服务必须由 services.exe 托管才能触发生命周期方法。
- 开发阶段加条件编译:用
#if DEBUG启动模拟上下文,让OnStart逻辑在控制台中可运行 - 发布前切回真实模式,确保
ServiceBase.Run(new MyService())正确调用 - 需要真机调试时,在
OnStart开头加Debugger.Launch(),系统会弹窗让你附加 VS 进程 - 别依赖文件日志查问题:先确认
EventLog能写入,再排查路径权限
路径读不到 appsettings.json?Environment.CurrentDirectory 是假的
服务启动后 Environment.CurrentDirectory 固定为 C:\Windows\System32,所有相对路径都会失效。Assembly.GetExecutingAssembly().Location 在单文件发布或 ReadyToRun 模式下也可能指向临时目录,不可靠。
- 唯一可信路径起点是
AppContext.BaseDirectory - 构造配置路径必须用:
Path.Combine(AppContext.BaseDirectory, "appsettings.json") - 写日志前先确保目录存在:
Directory.CreateDirectory(Path.GetDirectoryName(logPath)) - 若需访问用户目录(如读取某用户的 SQLite),不能硬切
HKEY_CURRENT_USER——服务没有“当前用户”,得换账户运行或显式模拟登录
最常被忽略的其实是权限和路径——哪怕 OnStart 秒返回、安装命令全对,只要日志写不到 EventLog、配置文件加载失败、或 Timer 没触发,服务就等于没活。动手前先确认 EventLog.WriteEntry 能打点,再往下走。











