运行程序写进win系统服务方法
0、sc介绍
SC 是用来与服务控制管理器和服务进行通信的命令行程序,可以利用该命令对win服务进行管理操作。注:sc的操作都需要管理员的权限
C:\Users\john>sc -help
错误: 未知命令
描述:
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-----------更改服务的所需权限。
qc--------------查询服务的配置信息。
qdescription----查询服务的描述。
qfailure--------查询失败时服务执行的操作。
qfailureflag----查询服务的失败操作标志。
qsidtype--------查询服务的服务 SID 类型。
qprivs----------查询服务的所需权限。
qtriggerinfo----查询服务的触发器参数。
qpreferrednode--查询首选的服务 NUMA 节点。
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
1、exe文件(nginx)
需要管理员权限执行以下命令
sc create nginxService binpath=xxx
例:
sc create nginxService binpath= C:\Users\BG264\Downloads\nginx-1.23.1\nginx-1.23.1\nginx.exe
[SC] CreateService 成功
注册进服务后默认不会开启,需要手动开启,可以进入管理开启,也可以用命令
sc start nginxService
2、Python文件
Python需要代码内注册服务,代码如下:(需要下载对应库文件)
from socket import socket
import servicemanager
import win32serviceutil
import win32service
import win32event
class AppServerSvc(win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.main()
def main(self):
pass
并且在程序启动的时候创建执行
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(AppServerSvc)
此外在运行Python脚本的时候需要添加 install 参数,例如
python3 main.py install
这样这个Python脚本就注册进win服务,同样不会自动启动,需要利用win的sc命令启动
# 启动服务
sc start MyService
# 停止服务
sc stop MyService
# 删除服务
sc delete MyService
3、.Net项目
.Net 需要在NuGet里面安装Microsoft.Extensions.Hosting.WindowsServices 包,然后修改Program.cs中启动配置类
Program.cs修改内容如下:
1、为Host增加UseWindowsServices方法。
2、注释掉config.SetBasePath方法
3、使用UseUrls方法指定应用程序启动后使用的端口号和协议(http、https)
完整配置方法如下:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseUrls("http://*:8080")
.UseStartup<Startup>();
});
修改后即可发布项目,利用sc命令创建一个win服务
sc create dotnetService binpath=C:\project\WebApplication1\WebApplication1\bin\Debug\net6.0\WebApplication1.exe
[SC] CreateService 成功
同样,服务创建后不会启动,需要手动启动
sc start dotnetService