Windows服务必须实现SERVICE_MAIN_FUNCTION入口并注册到SCM,否则启动报错1053;需用sc create安装、事件日志调试、协作式停止,严禁在ServiceMain中阻塞或直接exit。

Windows服务程序必须继承 SERVICE_MAIN_FUNCTION
直接用普通 main() 启动的 C++ 程序无法被 Windows 服务控制管理器(SCM)识别。必须实现一个符合 Windows 服务契约的入口函数,类型为 SERVICE_MAIN_FUNCTION,并在 StartServiceCtrlDispatcher() 中注册它。
常见错误是把服务逻辑写在 main() 里,然后用 sc create 强行注册——这会导致 SCM 启动后立即报错 1053(服务未及时响应启动或控制请求)。
-
SERVICE_MAIN_FUNCTION函数名任意,但签名必须是VOID WINAPI ServiceMain(DWORD argc, LPWSTR *argv) - 该函数内第一件事是调用
RegisterServiceCtrlHandlerEx()设置控制处理器,否则无法接收暂停/停止等指令 - 不要在
ServiceMain中执行耗时初始化;应另起线程处理业务,主线程保持对 SCM 的响应能力
服务安装必须用 sc.exe 或 CreateService(),不能双击运行
Windows 服务不是常规 GUI 或控制台程序,没有交互式桌面会话权限(默认情况下),也不能通过双击 exe 启动。安装必须由管理员权限发起,且需明确指定启动类型、账户上下文和二进制路径。
最简安装命令示例:sc create MyService binPath= "C:\path\to\service.exe" start= auto obj= ".\LocalSystem"
-
binPath=值前后不能有空格,路径含空格时需用英文引号包裹整个路径(如binPath= "\"C:\My App\svc.exe\"") -
obj=指定运行账户:LocalSystem权限高但不推荐;NT AUTHORITY\NetworkService更安全;自定义账户需提前授予“作为服务登录”权限(secpol.msc → 本地策略 → 用户权限分配) - 若服务需要访问网络资源或用户配置文件,
obj=不能设为LocalSystem(它没有用户 profile)
服务调试不能靠 printf + 控制台,要用事件日志或远程调试
服务进程默认无控制台,printf、std::cout、OutputDebugString(除非 Attach 到调试器)都看不到输出。直接加断点调试也常失败,因为 SCM 启动服务时可能不带调试环境。
- 首选方式:用
ReportEvent()写入 Windows 事件日志(Application 或自定义日志),配合eventvwr.msc查看 - 临时调试:在
ServiceMain开头加AllocConsole(); freopen("CONOUT$", "w", stdout);,仅限开发机测试(正式部署必须移除) - 远程调试:用 Visual Studio 远程调试器(msvsmon.exe),以服务账户身份运行调试器,并在服务代码中插入
DebugBreak() - 注意:启用
AllowServiceLogon权限后,某些账户才允许写入事件日志
服务停止时必须正确释放资源并响应 SERVICE_CONTROL_STOP
用户点击“停止服务”或执行 sc stop MyService 时,SCM 发送 SERVICE_CONTROL_STOP,你的控制处理器必须在 30 秒内返回(超时即被强制终止)。此时不能简单杀线程或 exit,而要协作式退出。
- 在控制处理器中设置全局标志(如
volatile BOOL g_ServiceStopRequested = FALSE),业务线程轮询该标志 - 避免使用
TerminateThread()—— 它跳过栈展开,极易导致资源泄漏或死锁 - 等待子线程自然退出(用
WaitForSingleObject()+ 超时),再调用SetServiceStatus()报告SERVICE_STOP_PENDING和最终SERVICE_STOPPED - 如果服务打开了命名管道、共享内存或全局对象,注意它们的生命周期是否跨服务重启;重复创建可能报错
ERROR_ALREADY_EXISTS
服务最难的部分不在注册,而在状态同步与资源生命周期管理——SCM 不关心你做什么,只关心你是否按时回应、是否干净退出。很多崩溃或卡死,根源是控制处理器没及时返回,或者主线程在等某个永远不结束的 I/O。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











