How to keep a windows service running

我怕爱的太早我们不能终老 提交于 2021-02-18 08:16:14

问题


Below is the framework for the windows service that I am running. In the event of an error, the error is logged and can be viewed in the event viewer. The problem is that the script just quits and does not restart again even though I have the recovery set to restart the service on the first, second and subsequent failures. Currently I have little error handling because I want to see what errors that may arise in the event viewer so that I can write code to handle these errors accordingly.

from win32api import CloseHandle, GetLastError, SetConsoleCtrlHandler
import os
import sys 
import time
import pythoncom
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket

class AppServerSvc (win32serviceutil.ServiceFramework):
    _svc_name_ = "my_service_name"
    _svc_display_name_ = "my service"

    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        SetConsoleCtrlHandler(lambda x: True, True)
        self.hWaitStop = win32event.CreateEvent(None,0,0,None)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.run = False

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_,''))
        self.run = True
        self.main()

    def main(self):
        while self.run == True
            pass          

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

Edit:

I tried to try: except around self.main but the outcome was still the same. The service did not restart when it crashed... Please anyone out there with any ideas? A service is not all that useful if it cannot restart in the event of a crash... Might as well run it as a .pyc

Edit:

below is an example of an error that may arise within my script... I don't believe this error message is particularly useful because what I am try to achieve is to have the service restart but none the less here is an example of an error that has crashed my service without it restarting:

The instance's SvcRun() method failed 
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\win32\lib\win32serviceutil.py", line 806, in SvcRun
    self.SvcDoRun()
  File "C:\Some_Service.py", line 46, in SvcDoRun
    self.main()
  File "Some_Service.py", line 61, in main
    ser = self.open_serial_port()
  File "Some_Service.py", line 70, in open_serial_port
    serial_connection.open()
  File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 56, in open
    raise SerialException("could not open port %s: %s" % (self.portstr, ctypes.WinError()))
SerialException: could not open port COM6: [Error 1225] The remote system refused the network connection. 
%2: %3

回答1:


Below is a service that just divides by zero to raise an error. If there is an error, an event is sent and the service exits using os._exit(-1). The value has to be anything but 0 so that the windows knows that the service didn't exit nicely.

from win32api import CloseHandle, GetLastError, SetConsoleCtrlHandler
import os
import sys
import time

import win32serviceutil
import win32service
import win32event
import servicemanager

import traceback



class AppServerSvc (win32serviceutil.ServiceFramework):
    _svc_name_ = "test"
    _svc_display_name_ = "test"

    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        SetConsoleCtrlHandler(lambda x: True, True)
        self.hWaitStop = win32event.CreateEvent(None,0,0,None)




    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.run = False
    def SvcDoRun(self):

        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_,''))
        self.run = True
        try: # try main
            self.main()
        except:
            servicemanager.LogErrorMsg(traceback.format_exc()) # if error print it to event log
            os._exit(-1)#return some value other than 0 to os so that service knows to restart


    def main(self):

        while self.run == True:
            time.sleep(30)         
            t = 1/0

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



回答2:


My suspicion is that your service is not in fact crashing, but completing before it has a chance to run. Have you tried inserting a sleep statement of a few seconds in the main function?




回答3:


Why don't you use a try-except for it ?

class AppServerSvc (win32serviceutil.ServiceFramework):
    _svc_name_ = "my_service_name"
    _svc_display_name_ = "my service"

    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        SetConsoleCtrlHandler(lambda x: True, True)
        self.hWaitStop = win32event.CreateEvent(None,0,0,None)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.run = False

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_,''))
        self.run = True
        self.main()

    def main(self):
        while self.run == True
            try :
                <your code>
            except :
                time.sleep(3)
                <may be an error log here>



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


来源:https://stackoverflow.com/questions/5315193/how-to-keep-a-windows-service-running

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!