python编写windows系统服务
1、环境准备
这里我们使用py39-x64版本
安装pywin32,选择对应的python版本,点我去下载
安装psutil模块,用于获取磁盘信息,用于创建日志写入目录
2、测试代码
import win32serviceutil import win32service import win32event import servicemanager import win32timezone import os import sys import logging from logging import handlers import psutil import time class WinSvc(win32serviceutil.ServiceFramework): _svc_name_ = 'PyWinSve' _svc_display_name_ = 'PyWinSveTest' _svc_description_ = 'python实现win服务测试,每隔5秒发送一次当前系统时间' def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) self.run=True self.StopEvent = win32event.CreateEvent(None, 0, 0, None) self.logger = self._getlogger() def _getlogger(self): logger = logging.getLogger('PyWinSve') logger.setLevel(logging.DEBUG) # 创建日志目录 partitions = [part[0] for part in psutil.disk_partitions()] for part in partitions: logDir = os.path.join(part, self._svc_name_, 'log') self.logDir = logDir if os.path.isdir(logDir): break try: os.makedirs(logDir) break except Exception as e: print(str(e)) # 每天创建一个日志文件,保存60个副本 logFileHandlerSplitTime = handlers.TimedRotatingFileHandler(os.path.join(self.logDir,'log.log'), when='D', interval=1, backupCount=60, encoding=None, delay=False, utc=False) logFormat = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s') logFileHandlerSplitTime.setFormatter(logFormat) logFileHandlerSplitTime.setLevel(logging.DEBUG) logger.addHandler(logFileHandlerSplitTime) return logger def SvcDoRun(self): """ 服务启动后运行得函数,需保证不推出,推出意味着服务停止 :return: """ self.logger.info('启动PyWinSvc服务...') while self.run: self.logger.info(time.strftime('%Y-%m-%d %H:%M:%S')) time.sleep(30) def SvcStop(self): """ 当停止服务时系统会调用该函数,但是系统关机时服务器停止不会调用 :return: """ self.logger.info('停止PyWinSvc服务...') self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.StopEvent) self.run = False # Press the green button in the gutter to run the script. if __name__ == '__main__': if len(sys.argv) == 1: try: evtsrc_dll = os.path.abspath(servicemanager.__file__) servicemanager.PrepareToHostSingle(WinSvc) servicemanager.Initialize('WinSvc', evtsrc_dll) servicemanager.StartServiceCtrlDispatcher() except Exception as e : print(e) else: win32serviceutil.HandleCommandLine(WinSvc)
打包后就可以用win服务管理命令进行服务的安装、启动、停止、卸载
3、问题
第一次安装卸载后,重新安装或启动时提示“指定服务已标记为删除”,关掉系统服务管理窗口后重新安装即可
启动服务提示函数不正确,单独挨个测试函数有没有问题,特别时init中的函数和在init中调用的函数
pyinstaller打包后提示No module name "win32timezone",在主模块中导入下win32timezone即可
打包时提示没权限写入,这个杀毒软件的锅,关闭杀毒软件或信任后多次重新打包写入