python管理Windows服务

Posted 黑月教主的空间

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python管理Windows服务相关的知识,希望对你有一定的参考价值。

上一篇介绍了pywin32模块,它的win32service子模块提供了对服务管理API的包装,相关API如下:

ChangeServiceConfig
ChangeServiceConfig2
CloseServiceHandle
ControlService
CreateDesktop
CreateService
CreateWindowStation
DeleteService
EnumDependentServices
EnumServicesStatus
EnumServicesStatusEx
EnumWindowStations
GetProcessWindowStation
GetServiceDisplayName
GetServiceKeyName
GetThreadDesktop
GetUserObjectInformation
LockServiceDatabase
OpenDesktop
OpenInputDesktop
OpenSCManager
OpenService
OpenWindowStation
QueryServiceConfig
QueryServiceConfig2
QueryServiceLockStatus
QueryServiceObjectSecurity
QueryServiceStatus
QueryServiceStatusEx
SetServiceObjectSecurity
SetServiceStatus
SetUserObjectInformation
StartService
UnlockServiceDatabase

 有了这些API,完成一些服务的基本操作,比如安装服务、停止服务、启动服务等完全不在话下,只不过都是直接调用API而已。

不过pywin32还有一个对win32service模块的包装,叫做 win32serviceutil,使用它可以更方便地对服务进行控制。

 

InstallService(pythonClassString, serviceName, displayName, startType = None, 
    errorControl = None, bRunInteractive = 0, serviceDeps = None, userName = None, 
    password = None, exeName = None, perfMonIni = None,perfMonDll = None, 
    exeArgs = None,description = None, delayedstart = None)  #安装服务

ChangeServiceConfig(pythonClassString, serviceName, startType = None, 
    errorControl = None, bRunInteractive = 0, serviceDeps = None, 
    userName = None, password = None,exeName = None, displayName = None, 
    perfMonIni = None, perfMonDll = None,exeArgs = None,
    description = None, delayedstart = None)  #更改服务设置

#以上两个函数的第一个参数pythonClassString是为Python编写的Windows服务准备的,非Python服务则不需要,直接填None即可

RemoveService(serviceName)  #删除服务
ControlService(serviceName, code, machine = None)  #控制服务,code的具体定义参考MSDN的对ControlService的介绍
StopService(serviceName, machine = None) #停止服务
StartService(serviceName, args = None, machine = None) #启动服务
RestartService(serviceName, args = None, waitSeconds = 30, machine = None) #重启服务
QueryServiceStatus(serviceName, machine=None)  #查询服务状态

 

 大部分API只需要提供服务名称就可以了,调用起来非常简单。

比如 win32serviceutil.StopService("Spooler") 就可以停止Spooler服务了。

对于 win32serviceutil.QueryServiceStatus()这个函数,它实际返回的是win32service.QueryServiceStatus的返回结果。

从MSDN和pywin32的帮助文件可知,win32service.QueryServiceStatus的返回值是一个元组,如下:

SERVICE_STATUS Object
A Win32 service status object is represented by a tuple:
Items
[0] int : serviceType
The type of service.
[1] int : serviceState
The current state of the service.
[2] int : controlsAccepted
The controls the service accepts.
[3] int : win32ExitCode
The win32 error code for the service.
[4] int : serviceSpecificErrorCode
The service specific error code.
[5] int : checkPoint
The checkpoint reported by the service.
[6] int : waitHint
The wait hint reported by the service

 服务状态实际上是第1个元素(从0开始计数)

写个函数包装一下,并附带上控制功能:

import win32service
import win32serviceutil
import win32api

def GetSvcStatus(svcname):
    svcstatusdic = {
    #The service continue is pending.
    win32service.SERVICE_CONTINUE_PENDING:"continue pending", 
    #The service pause is pending.
    win32service.SERVICE_PAUSE_PENDING:"pause pending",
    #The service is paused.
    win32service.SERVICE_PAUSED:"paused" , 
    #The service is running.
    win32service.SERVICE_RUNNING:"running",
    #The service is starting.
    win32service.SERVICE_START_PENDING:"start pending", 
    # The service is stopping.
    win32service.SERVICE_STOP_PENDING:"stop pending" ,
    #The service is not running.
    win32service.SERVICE_STOPPED:"stoped"
    }
    status = win32serviceutil.QueryServiceStatus(svcname)
    if status:
        return svcstatusdic.get(status[1],"unknown")
    else:
        return "error"

svcname = "Spooler"
status = GetSvcStatus(svcname)
print("{} current status : {}".format(svcname,status))
if status == "running":
    win32serviceutil.StopService(svcname)
else:
    win32serviceutil.StartService(svcname)
win32api.Sleep(1000)
status = GetSvcStatus(svcname)
print("After Control,{} current status : {}".format(svcname,status))

输出结果如下:

掌握该模块的使用,对Windows平台的运维管理还是有相当帮助的。

以上是关于python管理Windows服务的主要内容,如果未能解决你的问题,请参考以下文章

scrapy按顺序启动多个爬虫代码片段(python3)

python管理Windows服务

python使用上下文对代码片段进行计时,非装饰器

SpringCloud系列四:Eureka 服务发现框架(定义 Eureka 服务端Eureka 服务信息Eureka 发现管理Eureka 安全配置Eureka-HA(高可用) 机制Eur(代码片段

[未解决问题记录]python asyncio+aiohttp出现Exception ignored:RuntimeError('Event loop is closed')(代码片段

使用 Git 来管理 Xcode 中的代码片段