sc create 创建服务时必须显式指定 binPath=、start= 和 obj= 等关键参数,否则因权限、路径或环境问题易启动失败;服务需实现 ServiceMain 和 HandlerEx 回调,Python/Go/Rust 需专用封装或链接 advapi32.lib。
sc create 创建服务时路径和权限必须显式指定
直接用 sc create 不加关键参数,服务大概率启动失败——windows 默认以 localsystem 身份运行,但你的可执行文件很可能依赖用户环境变量、当前目录或网络凭据。
必须显式指定 binpath=(注意等号后有空格)、start= 类型,并考虑 obj= 指定运行账户:
sc create MyService binPath= "C:\tools\myservice.exe" start= auto obj= ".\MyUser" password= "P@ssw0rd"
常见错误:binPath= 值没用英文双引号包裹(路径含空格时报错 1053: 服务没有及时响应启动或控制请求);start= 后漏空格(被识别为参数名而非值);未赋予目标账户“作为服务登录”权限(需用 secpol.msc 或 gpedit.msc 配置)。
sc start/stop 失败常因服务处于“暂停”或“禁用”状态
执行 sc start MyService 返回 1053 或 1056,不一定是程序问题,先查真实状态:
-
sc query MyService看STATE字段:若为4 RUNNING却仍报错,说明进程已挂但 SCM 未感知; - 若为
1 STOPPED但START_TYPE是DISABLED,得先sc config MyService start= demand; - 若
STATE是7 PAUSED,sc start无效,得用sc continue MyService。
服务启动超时默认 30 秒,若程序初始化慢,需同步调大 servicesPipeTimeout 注册表项(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control),否则强制标记为失败。
sc delete 删除服务前必须确保它已停止且无残留进程
sc delete 只是移除 SCM 数据库条目,不杀进程。若 myservice.exe 还在后台跑着,删完再 sc create 会因端口/文件锁冲突导致新服务无法启动。
- 先
sc stop MyService,再tasklist /fi "imagename eq myservice.exe"确认进程消失; - 若进程僵死,用
taskkill /f /im myservice.exe强制结束; - 删服务后,检查
sc query MyService应返回[SC] EnumQueryServicesStatus:OpenService FAILED 1060(服务不存在),才算真正清理干净。
注意:sc delete 不会删除磁盘上的二进制文件或日志,这些得手动清理。
服务程序自身必须实现 ServiceMain 和 HandlerEx 回调
sc create 只是注册入口,真正在 Windows 服务上下文中运行,要求程序用 Win32 API 实现标准服务契约:
- 入口点必须调用
StartServiceCtrlDispatcher并传入SERVICE_TABLE_ENTRY数组; - 每个服务项的
ServiceMain函数里,要第一时间调用RegisterServiceCtrlHandlerEx绑定控制处理器; - 必须处理
SERVICE_CONTROL_STOP和SERVICE_CONTROL_SHUTDOWN,否则sc stop会卡住或触发系统强制终止。
用 Python 写服务?别直接跑 python.exe script.py —— 得用 pywin32 的 win32serviceutil.InstallService 封装,否则 SCM 无法通信。Go 或 Rust 也得链接 advapi32.lib 并导出对应符号。










