1

I have a service, as follows:

"""
The most basic (working) CherryPy 3.1 Windows service possible.
Requires Mark Hammond's pywin32 package.
"""

import cherrypy
import win32serviceutil
import win32service
import sys
import __builtin__

__builtin__.theService = None

class HelloWorld:
    """ Sample request handler class. """

    def __init__(self):
        self.iVal = 0

    @cherrypy.expose
    def index(self):

        try:

            self.iVal += 1 

            if self.iVal == 5:
                sys.exit()
            return "Hello world! " + str(self.iVal) 

        except SystemExit:
            StopServiceError(__builtin__.theService)


class MyService(win32serviceutil.ServiceFramework):
    """NT Service."""

    _svc_name_ = "CherryPyService"
    _svc_display_name_ = "CherryPy Service"
    _svc_description_ = "Some description for this service"

    def SvcDoRun(self):
        __builtin__.theService = self
        StartService()


    def SvcStop(self):
        StopService(__builtin__.theService)


def StartService():

    cherrypy.tree.mount(HelloWorld(), '/')

    cherrypy.config.update({
        'global':{
            'tools.log_tracebacks.on': True,
            'log.error_file': '\\Error_File.txt',
            'log.screen': True,
            'engine.autoreload.on': False,
            'engine.SIGHUP': None,
            'engine.SIGTERM': None
            }
        })

    cherrypy.engine.start()
    cherrypy.engine.block()


def StopService(classObject):
    classObject.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
    cherrypy.engine.exit()
    classObject.ReportServiceStatus(win32service.SERVICE_STOPPED)


def StopServiceError(classObject):
    classObject.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
    cherrypy.engine.exit()
    classObject.ReportServiceStatus(serviceStatus=win32service.SERVICE_STOPPED, win32ExitCode=1, svcExitCode=1)

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(MyService)

I want windows to restart the service when the sys.ext() cause the service to exit. Does anyone know how to make it do this?

David Webb
  • 190,537
  • 57
  • 313
  • 299
William Troup
  • 12,739
  • 21
  • 70
  • 98
  • Try the answer to this question: [http://stackoverflow.com/questions/220382/how-can-a-windows-service-programmatically-restart-itself](http://stackoverflow.com/questions/220382/how-can-a-windows-service-programmatically-restart-itself) – David Sykes Jun 23 '09 at 10:30

2 Answers2

4

A non programming-related option:

A windows service can be configured for recovery. Select the recovery tag of the service properties window. You can select to Restart the Service after the first, second or subsequent failures.

A simple idea - why don't you drop the sys.exit() call? This way the service just continues to run and you don't have to deal with restarting it. If you really need to know when self.iVal reaches 5, you can report to the event logger (and perhaps reset the counter).

gimel
  • 83,368
  • 10
  • 76
  • 104
  • I've done this, but it still does not restart the service after a minute. – William Troup Jun 23 '09 at 10:54
  • Look for clues in eventlog items under system / service control manager. – gimel Jun 23 '09 at 11:15
  • @gimel, this "non-programming option" **doesn't work**. Python services built with py2exe are not restarted after failure even when Windows is configured to do so in the way you suggest. – Charles Duffy Sep 02 '14 at 03:26
  • This is the only thing that worked for me when using and EXE compiled with pyinstaller. `os.kill(os.getpid(), signal.SIGABRT)` did not work. `sys.exit(-1)` is still required if the program does not end with a non-zero code on it's own. – rlat Feb 09 '17 at 10:37
  • @rlat your comment is unclear. How exactly did you get this to work? – AbrahamCoding Jul 22 '20 at 03:06
  • And are you using pyinstaller in one-file or one-folder mode? – AbrahamCoding Jul 22 '20 at 03:08
  • @ModestLeech My answer is 6 year old so I don't work with this any more and have only a vague recollection of what the solution (or problem) was. What I think I was trying to say was "If the services doesn't exit with non-zero code, it will not be restarted" (because zero code mean success / planned termination). – rlat Jul 22 '20 at 13:55
  • @rlat thanks for the response. I got it working in the end – AbrahamCoding Jul 23 '20 at 03:33
2

I've had exactly the same issue: trying to make a Python-based service exit with an error code so that the services framework can restart it. I tried the approach with ReportServiceStatus(win32service.SERVICE_STOP_PENDING, win32ExitCode=1, svcExitCode=1) as well as sys.exit(1) but none of them prompted Windows to restart the service, despite the latter showing up as an error in the event log. I ended up not relying on the services framework and just doing this:

def SvcDoRun(self):
    restart_required = run_service() # will return True if the service needs
                                     # to be restarted
    if restart_required:
        subprocess.Popen('sleep 5 & sc start %s' % self._svc_name_, shell=True)
narthi
  • 2,188
  • 1
  • 16
  • 27