Skip to content

Instantly share code, notes, and snippets.

@deajan
Created January 24, 2019 01:17
Show Gist options
  • Save deajan/4af18971ca0e2315ebdf872c57feeea6 to your computer and use it in GitHub Desktop.
Save deajan/4af18971ca0e2315ebdf872c57feeea6 to your computer and use it in GitHub Desktop.
python_service
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