Created
January 24, 2019 01:17
-
-
Save deajan/4af18971ca0e2315ebdf872c57feeea6 to your computer and use it in GitHub Desktop.
python_service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import win32serviceutil | |
import win32service | |
import win32event | |
import win32api | |
import servicemanager | |
import os | |
import sys | |
from time import sleep | |
import socket | |
module_path = sys.argv[0] | |
module_file = os.path.splitext(os.path.abspath(module_path))[0] + '.exe' | |
logger.info('module = %s ' % module_file) | |
MODULE_FILENAME = module_file | |
# http://code.activestate.com/recipes/551780-win-services-helper/ | |
class SMWinservice(win32serviceutil.ServiceFramework): | |
'''Base class to create winservice in Python''' | |
_svc_name_ = 'mysvc' | |
_svc_display_name_ = 'some name' | |
_svc_description_ = 'some desc' | |
@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) | |
self.is_running = False | |
def SvcStop(self): | |
''' | |
Called when the service is asked to stop | |
''' | |
self.stop() | |
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) | |
win32event.SetEvent(self.hWaitStop) | |
self.is_running = False | |
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.is_running = True | |
self.main() | |
def instart(cls, name, display_name=None, stay_alive=True): | |
''' Install and Start (auto) a Service | |
cls : the class (derived from Service) that implement the Service | |
name : Service name | |
display_name : the name displayed in the service manager | |
stay_alive : Service will stop on logout if False | |
''' | |
cls._svc_name_ = name | |
cls._svc_display_name_ = display_name or name | |
cls._svc_reg_class_ = '%s.%s' % (MODULE_FILENAME, cls.__name__) | |
if stay_alive: win32api.SetConsoleCtrlHandler(lambda x: True, True) | |
try: | |
win32serviceutil.InstallService( | |
cls._svc_reg_class_, | |
cls._svc_name_, | |
cls._svc_display_name_, | |
startType=win32service.SERVICE_AUTO_START | |
) | |
print('Install ok') | |
win32serviceutil.StartService( | |
cls._svc_name_ | |
) | |
print('Start ok') | |
except Exception as x: | |
print(str(x)) | |
def start(self): | |
''' | |
Override to add logic before the start | |
eg. running condition | |
''' | |
logger.info('service stating') | |
def stop(self): | |
''' | |
Override to add logic before the stop | |
eg. invalidating running condition | |
''' | |
logger.info('service stopping') | |
def main(self): | |
''' | |
Main class to be ovverridden to add logic | |
''' | |
logger.info('service running') | |
while self.is_running: | |
logger.info('run run run little service') | |
sleep(4) | |
# 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__': | |
SMWinservice.parse_command_line() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment