在linux中把一个程序封装为服务开机启动很简单,在window中是否也有这种操作呢, 于是研究了下使用sc打包封装为 Windows 服务这样就可以用开机自启的方式愉快的使用了,这里介绍下相关的操作。
SC 是用来与服务控制管理器和服务进行通信的命令行程序。
sc.exe为服务控制管理service control manager,用于对计算机的系统服务进行管理,实现注册,运行,暂停,自启等基础操作,用户能够将符合Windows系统服务化条件的程序进行本地系统后台服务化运行,注册到服务注册表目录下的程序,通过sc的指令实现程序执行状态的切换和管理。
注意
- 所有的等号和值之间需要一个空格(等号前不要空格,等号后要一个空格) !!
- 当路径中有空格时会导致程序起动失败,需要使用嵌套引号括起来,内部引号需要使用反斜杠进行转义
例如:
sc create wizops binpath= "\"C:\Program Files\wizops\wizops.exe\" server" type= own start= auto displayname= wizops
常用指令
创建服务
sc create [service_name] binpath= "D:\test\test.exe"
查询服务
sc query [service_name]
删除服务
sc delete [service_name]
启动服务
sc start [service_name]
# 或
net start [service_name]
停止服务
sc stop [service_name]
# 或
net stop [service_name]
案例
创建一个python文件 server.py
import http.server
import socketserver
PORT = 9090
Handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
把此程序注册为服务
sc create aac binpath= "C:\Python39\python.exe --C:\Python39\myserver.py"
还没有成功😤
错误
[SC] StartService 失败 1053:
服务没有及时响应启动或控制请求。
等待 xxx 服务的连接超时(30000 毫秒)。
等待服务连接超时的问题可能表明服务启动时无法成功建立所需的连接或资源。以下是一些可能的解决方法:
1、检查服务的依赖项
服务可能依赖于其他服务或资源。确保这些依赖项都已经启动。你可以在服务注册时使用 depend= Dependencies 参数指定依赖项。
替换 Dependencies 为实际的依赖项。
2、检查服务脚本中的资源使用
确保你的服务脚本在启动时没有尝试访问不可用的资源,例如网络共享、数据库等。如果服务依赖于外部资源,请确保这些资源在服务启动时是可用的。
3、检查防火墙和安全软件
防火墙或安全软件可能阻止了服务与网络或系统资源的连接。确保防火墙规则允许服务访问所需的资源。
4、检查端口冲突
如果服务使用网络连接,确保服务所需的端口没有被其他应用程序占用。尝试更改服务使用的端口,或者确保其他应用程序释放了该端口。
5、查看事件查看器中的详细信息
打开 Windows 事件查看器,查看系统事件日志,特别是“应用程序”和“系统”类别,以获取关于服务启动失败的更多详细信息。查看是否有更多的错误消息或警告,这有助于定位问题的根本原因。
还不行,就放弃吧,看这个吧 nssm创建window服务
详细参数
使用 sc /? 或 help sc
Z:\>sc /?
错误: 未知命令
描述:
SC 是用来与服务控制管理器和服务进行通信
的命令行程序。
用法:
sc <server> [command] [service name] <option1> <option2>...
<server> 选项的格式为 "\\ServerName"
可通过键入以下命令获取有关命令的更多帮助: "sc [command]"
命令:
query-----------查询服务的状态,
或枚举服务类型的状态。
queryex---------查询服务的扩展状态,
或枚举服务类型的状态。
start-----------启动服务。
pause-----------向服务发送 PAUSE 控制请求。
interrogate-----向服务发送 INTERROGATE 控制请求。
continue--------向服务发送 CONTINUE 控制请求。
stop------------向服务发送 STOP 请求。
config----------更改服务的配置(永久)。
description-----更改服务的描述。
failure---------更改失败时服务执行的操作。
failureflag-----更改服务的失败操作标志。
sidtype---------更改服务的服务 SID 类型。
privs-----------更改服务的所需特权。
managedaccount--更改服务以将服务帐户密码
标记为由 LSA 管理。
qc--------------查询服务的配置信息。
qdescription----查询服务的描述。
qfailure--------查询失败时服务执行的操作。
qfailureflag----查询服务的失败操作标志。
qsidtype--------查询服务的服务 SID 类型。
qprivs----------查询服务的所需特权。
qtriggerinfo----查询服务的触发器参数。
qpreferrednode--查询服务的首选 NUMA 节点。
qmanagedaccount-查询服务是否将帐户
与 LSA 管理的密码结合使用。
qprotection-----查询服务的进程保护级别。
quserservice----查询用户服务模板的本地实例。
delete ----------(从注册表中)删除服务。
create----------创建服务(并将其添加到注册表中)。
control---------向服务发送控制。
sdshow----------显示服务的安全描述符。
sdset-----------设置服务的安全描述符。
showsid---------显示与任意名称对应的服务 SID 字符串。
triggerinfo-----配置服务的触发器参数。
preferrednode---设置服务的首选 NUMA 节点。
GetDisplayName--获取服务的 DisplayName。
GetKeyName------获取服务的 ServiceKeyName。
EnumDepend------枚举服务依赖关系。
以下命令不需要服务名称:
sc <server> <command> <option>
boot------------(ok | bad)指示是否应将上一次启动另存为
最近一次已知的正确启动配置
Lock------------锁定服务数据库
QueryLock-------查询 SCManager 数据库的 LockStatus
示例:
sc start MyService
QUERY 和 QUERYEX 选项:
如果查询命令带服务名称,将返回
该服务的状态。其他选项不适合这种
情况。如果查询命令不带参数或
带下列选项之一,将枚举此服务。
type= 要枚举的服务的类型(driver, service, userservice, all)
(默认 = service)
state= 要枚举的服务的状态 (inactive, all)
(默认 = active)
bufsize= 枚举缓冲区的大小(以字节计)
(默认 = 4096)
ri= 开始枚举的恢复索引号
(默认 = 0)
group= 要枚举的服务组
(默认 = all groups)
语法示例
sc query - 枚举活动服务和驱动程序的状态
sc query eventlog - 显示 eventlog 服务的状态
sc queryex eventlog - 显示 eventlog 服务的扩展状态
sc query type= driver - 仅枚举活动驱动程序
sc query type= service - 仅枚举 Win32 服务
sc query state= all - 枚举所有服务和驱动程序
sc query bufsize= 50 - 枚举缓冲区为 50 字节
sc query ri= 14 - 枚举时恢复索引 = 14
sc queryex group= "" - 枚举不在组内的活动服务
sc query type= interact - 枚举所有不活动服务
sc query type= driver group= NDIS - 枚举所有 NDIS 驱动程序