python service on win32
概要
pywin32 を使用し、python でサービスを実装する。
不完全なベースクラスWsvcと、Wsvcを継承し機能を実装するサービスクラスSoneの2つを作成する。
サービスに関わる作業一覧
サービス・クラスSone
#!/usr/bin/python3 # # sone.py # from time import sleep from wsvc import Wsvc import logging logging.basicConfig( filename = 'c:\\sone.log', level = logging.DEBUG, format = '[service-one] %(levelname)-7.7s %(message)s') class Sone(Wsvc): _svc_name_ = "Sone" _svc_display_name_ = "Service 1" _svc_description_ = "Enjoy!" def start(self): self.isrunning = True def stop(self): self.isrunning = False def main(self): while self.isrunning: logging.info('sone main.') sleep(5) if __name__ == '__main__': Sone.parse_command_line()
ベース・クラスWsvc
#!/usr/bin/python3 # # wsvc.py # import socket import win32serviceutil import servicemanager import win32event import win32service class Wsvc(win32serviceutil.ServiceFramework): '''Base class to create winservice in Python''' _svc_name_ = 'pythonService' _svc_display_name_ = 'Python Service' _svc_description_ = 'Python Service Description' @classmethod def parse_command_line(cls): ''' ClassMethod to parse the command line ''' win32serviceutil.HandleCommandLine(cls) def __init__(self, args): ''' Constructor of the winservice ''' win32serviceutil.ServiceFramework.__init__(self, args) self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) socket.setdefaulttimeout(60) def SvcStop(self): ''' Called when the service is asked to stop ''' self.stop() self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) def SvcDoRun(self): ''' Called when the service is asked to start ''' self.start() servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, '')) self.main() def start(self): ''' Override to add logic before the start eg. running condition ''' pass def stop(self): ''' Override to add logic before the stop eg. invalidating running condition ''' pass def main(self): ''' Main class to be ovverridden to add logic ''' pass # entry point of the module: copy and paste into the new module # ensuring you are calling the "parse_command_line" of the new created class if __name__ == '__main__': Wsvc.parse_command_line()