Skip to content

使用 sc 命令注册程序为开机自启服务

sc 命令

🔧注册服务

shell
# cmd 语法格式:
sc create <ServiceName> binpath= "<ExePath> <ExeArgs>" start= auto displayname= "<DisplayName>" depend= <ServiceName> type= own

参数详解:

参数说明
binpath=程序绝对路径(路径含空格时需用双引号包裹,如 "C:\Program Files\app.exe")。若程序启动需要参数,则需作为 binpath= 的一部分传入。
start=启动类型:auto:系统启动时自动加载服务,适用于需常驻后台的核心服务(如数据库)。delayed-auto:系统启动后延迟启动(避免拖慢开机速度),适用于非关键服务(如日志采集)。demand手动启动(需通过 sc start 或服务管理器触发),适用于调试期或按需使用的服务。disabled:禁用服务(无法通过常规方式启动),适用于临时停用或存在冲突的服务。
displayname=服务显示名称(在 services.msc 中可见)。在服务管理器(services.msc)中替代服务注册名(如:Redis),以提升可读性。
type=服务类型:own(独立进程)share(共享进程)
depend=依赖的服务(如: depend= Tcpip)。多个服务名用 / 分隔(空格无效)比如:depend= Tcpip/Dnscache/MySQL

操作步骤:

以管理员身份运行 CMD/PowerShell(或右键选择“以管理员身份运行”)。

shell
# 执行注册命令(示例):
sc create MyService binpath= "C:\app\service.exe"  start= auto displayname= "My Background Service" depend= Tcpip type= own

# 成功后提示:
[SC] CreateService SUCCESS

⚠️关键注意事项:

txt
- 等号后必须有空格(如 binpath= "路径" 正确,binpath="路径" 错误)。
- 路径含空格时,外层引号需转义:binpath= \"C:\Program Files\app.exe\"。
- depend =Tcpip:依赖服务不存在将导致启动失败。若 Tcpip 未运行,依赖它的服务会报错 错误 1068:依赖服务组启动失败。
- 依赖服务名称需精确匹配。
  - 通过 sc query 或 services.msc 查看服务的真实名称(非显示名称):
  - sc query state= all | findstr "SERVICE_NAME"
- 若程序非服务专用框架开发,可能启动失败(错误 1053),需改用 WinSW 等工具封装。

查找服务的真实名称:

shell
# 注意:此处的 "SERVICE_NAME" 就是字符串,不是变量。
sc query state= all | findstr "SERVICE_NAME"

sc create 命令返回状态码

在 Windows 命令行环境中,使用 sc create 命令创建系统服务时,其返回的状态码(通过 %errorlevel% 获取)遵循标准 Windows 错误码规范。以下是常见状态码及其含义总结:

状态码含义原因及解决方案
0操作成功 ✅服务创建成功,可在服务管理器 (services.msc) 查看或通过 sc query 服务名 验证。
2系统找不到指定文件 ❌binPath= 参数指定的可执行文件路径错误(检查路径拼写、空格及文件是否存在)。
5拒绝访问 🚫 ️当前用户权限不足(需以管理员身份运行 CMD/PowerShell)。
87参数错误 ⚠️命令语法错误(如 binPath= 等号后缺少空格,或未知参数)。
1053服务未及时响应服务程序启动超时或路径指向的执行文件初始化失败(检查程序路径是否有效)。
1058服务已存在或禁用 🚫服务名称重复(需先删除旧服务:sc delete 服务名)或目标服务被标记为禁用。
1072服务已标记为要删除❌指定的服务已标记为要删除(需先停止运行中的旧服务:sc stop 服务名, 停止后就没有这个服务进程了)。

注:完整错误码列表可参考 Microsoft 系统错误代码文档

🔧服务描述

添加/修改描述,需在服务创建后执行。

shell
sc description MyService "这是一个 Redis 服务。"

支持中文描述,长度建议 ≤ 256 字符。

🔧修改服务

使用 sc config 调整已注册服务的启动类型:

shell
sc config MyService start= delayed-auto

🔧启动服务

shell
sc start MyService  

# 或 
net start MyService

🔧停止服务

shell
sc stop MyService
# 或 
net stop MyService

🔧重启服务

sc 命令标准重启流程:

shell
# 停止服务
sc stop <ServiceName>

# sc 命令是异步执行的,等待 5 秒确保服务完全释放资源
timeout /t 5 /nobreak

# 启动服务
sc start <ServiceName>

net 命令标准重启流程(推荐):

shell
# 停止服务
net stop <ServiceName>

# 启动服务(net 命令是同步执行的,无需使用 timeout 等待)
net start <ServiceName>

关键点:

  • 必须添加等待间隔:sc stop 是异步命令,需用 timeout 或 ping 延迟(如 ping 127.0.0.1 -n 5 >nul),否则可能因资源未释放导致重启失败 2。
  • 服务名称准确性:
    • 通过 services.msc → 右键服务 → “属性” → 查看服务名称(非显示名称)。
    • 或用 sc query state= all | findstr <ServiceName> 验证。

🗑️卸载服务

标准卸载流程:

shell
# 停止服务:
sc stop MyService
# 或 
net stop MyService

# 删除服务:
sc delete MyService

# 成功提示:
[SC] DeleteService SUCCESS

💣 处理顽固服务: 若提示 [SC] DeleteService 失败 1072: 指定的服务已标记为删除:

  • 强制删除注册表项:
    • 打开注册表:regedit,导航至:
      • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MyService
    • 删除整个 MyService 项。
  • 重启系统以生效。

⚠️常见错误与解决方案

错误代码原因解决方法
1053服务未及时响应检查程序是否支持服务模式;路径引号是否正确;依赖服务是否启动
5权限不足管理员身份运行 CMD;关闭 UAC 临时处理(需重启)
1060服务不存在/名称错误通过 services.msc 确认服务注册名称(非显示名称)
1072服务已标记删除删除注册表项并重启

🔄服务管理扩展命令

命令作用
sc query MyService查询服务状态
sc config start= demand改为手动启动
sc failure MyService配置服务失败时重启策略

关于 sc 命令 和 net 命令

sc 命令是异步执行的,而 net 命令是同步执行的。

  • 优先使用 sc 命令的场景:
    • 注册系统服务、设置延迟启动(start= delayed-auto)、添加服务依赖。
  • 优先使用 net 命令的场景:
    • 快速启停服务、映射网络驱动器、批量管理域用户。

一句话总结(最佳实践):创建/删除服务使用 sc 命令,启动/停止/重启服务使用 net 命令。

示例

注册 Redis 开机自启动服务

已知手动启动 redis 脚本名称为:start_redis.cmd,内容如下:

cmd
@echo off
title=Redis

cd /d %~dp0
redis-server.exe redis.conf

则安装 redis 为服务的脚本名称为:install_redis.cmd,内容如下:

cmd
@echo off
cd /d %~dp0
sc create redis binpath= "\"%cd%\redis-server.exe\" --service-run redis.conf" displayname= "Redis Service" start= auto depend= Tcpip type= own
sc description redis "Redis Service 提供高性能键值存储服务"

# 倒计时 10 秒继续执行。有这个可以观察服务是否注册成功。
timeout /t 10 /nobreak
net start redis

效果验证

假如程序位置在:C:\redis\redis-server.exe

  • 服务管理器显示名称:Redis Service
  • 描述提示:Redis Service 提供高性能键值存储服务
  • 实际启动命令:C:\redis\redis-server.exe --service-run redis.conf

可替换使用

--service-run 中的 %CD% 参数。如下:

cmd
@echo off
cd /d %~dp0
sc create redis binpath= "\"%cd%\redis-server.exe\" --service-run \"%cd%\redis.conf\"" displayname= "Redis Service" start= auto depend= Tcpip type= own
sc description redis "Redis Service"
timeout /t 10 /nobreak
net start redis

关于引号的理解,可参考下面示例:

txt
sc create redis binpath= "\"C:\redis\redis-server.exe\" --service-run redis.conf" start= auto

启动、停止、重启 Redis

shell
# 启动
net start redis

# 停止
net stop redis

# 重启
net start redis
net stop redis

样例

install_redis.cmd

batch
@echo off
cd /d %~dp0

sc create redis binpath= "\"%cd%\redis-server.exe\" --service-run redis.conf" displayname= "Redis Service" start= auto depend= Tcpip type= own

if %errorlevel% neq 0 (
    if %errorlevel% equ 2 echo - 系统找不到指定的文件,请检查 binpath 参数!
    if %errorlevel% equ 5 echo - 请右键【以管理员身份运行】此脚本!
    if %errorlevel% equ 87 echo - 参数错误!请检查等号后面的空格或参数值!
    if %errorlevel% equ 1058 echo - 服务已存在!
    echo [错误] 服务注册失败!错误代码= %errorlevel%
    pause
    exit
)

sc description redis "Redis Service 提供高性能键值存储服务"

echo 服务注册成功!

net start redis

pause

install_nacos.cmd

由于 nacos 启动是通过 nacos/bin 目录下的命令 startup.cmd -m standalone 来启动的,而 sc create 命令只支持标准 .exe 程序注册为服务,不支持注册一个 .cmd 脚本作为 binpath 参数。

因此,nacos 只能通过 https://github.com/winsw/winsw 工具打包成 nacos.exe 后再注册。