上一篇介绍了pywin32模块,它的win32service子模块提供了对服务管理API的包装,相关API如下:
ChangeServiceConfigChangeServiceConfig2CloseServiceHandleControlServiceCreateDesktopCreateServiceCreateWindowStationDeleteServiceEnumDependentServicesEnumServicesStatusEnumServicesStatusExEnumWindowStationsGetProcessWindowStationGetServiceDisplayNameGetServiceKeyNameGetThreadDesktopGetUserObjectInformationLockServiceDatabaseOpenDesktopOpenInputDesktopOpenSCManagerOpenServiceOpenWindowStationQueryServiceConfigQueryServiceConfig2QueryServiceLockStatusQueryServiceObjectSecurityQueryServiceStatusQueryServiceStatusExSetServiceObjectSecuritySetServiceStatusSetUserObjectInformationStartServiceUnlockServiceDatabase
有了这些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 ObjectA Win32 service status object is represented by a tuple:Items[0] int : serviceTypeThe type of service.[1] int : serviceStateThe current state of the service.[2] int : controlsAcceptedThe controls the service accepts.[3] int : win32ExitCodeThe win32 error code for the service.[4] int : serviceSpecificErrorCodeThe service specific error code.[5] int : checkPointThe checkpoint reported by the service.[6] int : waitHintThe wait hint reported by the service
服务状态实际上是第1个元素(从0开始计数)
写个函数包装一下,并附带上控制功能:
import win32serviceimport win32serviceutilimport win32apidef 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平台的运维管理还是有相当帮助的。