我想在Windows上运行一些Python代码作为服务。我顺便使用Python 3.6。 我把这个通用的Windows守护进程类放在一起(来自各种来源)。当我运行它,它运作良好。但是,当我将其子类化为在包含一些实际有用代码的服务中使用时,服务未启动但立即返回 ,错误服务未响应启动或控制请求及时的时尚。
所以 - 请参阅下面的示例 - windows_daemon.py 有效,但 new_service.py 却没有。
当我将它子类化时,有谁可以看到为什么我的python服务没有在Windows上启动?
import time
import sys
import logging
import logging.handlers
import traceback
import win32serviceutil
import win32service
import win32event
import servicemanager
import os
def handle(instance):
win32serviceutil.HandleCommandLine(instance)
class windows_daemon(win32serviceutil.ServiceFramework):
# you can NET START/STOP the service by the following name
_svc_name_ = "Daemon"
# this text shows up as the service name in the Service
# Control Manager (SCM)
_svc_display_name_ = "Windows daemon"
# this text shows up as the description in the SCM
_svc_description_ = "This service controls some stuff"
# list dependencies
_svc_deps_ = ["EventLog"]
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self,args)
# create an event to listen for stop requests on
self.hWaitStop = win32event.CreateEvent(None,0,0,None)
self.Alive = True
self.host = os.environ['COMPUTERNAME'].lower()
self.pid = os.getpid()
self.name = self._svc_display_name_
self.rootlogger = logging.getLogger()
#self.logger = logging.getLogger("{}".format(self.name))
self.rootlogger.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler = logging.handlers.RotatingFileHandler("{0}\log\{1}.log".format(os.path.dirname(os.path.realpath(__file__)), self.name), maxBytes = 1000000, backupCount = 5)
handler.setFormatter(formatter)
self.rootlogger.addHandler(handler)
self.logger = logging.getLogger("service")
# called when we're being shut down
def SvcStop(self):
self.logger.info("stopping service")
# tell the SCM we're shutting down
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
# fire the stop event
win32event.SetEvent(self.hWaitStop)
self.Alive = False
# core logic of the service
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.logger.debug("starting service")
self.timeout = 100
try:
self.main()
self.logger.debug("no exception in main")
exitcode = 0
except Exception as e:
#could also debug to Windows event log
#servicemanager.LogErrorMsg(traceback.format_exc())
#servicemanager.LogErrorMsg("{}".format(e))
try:
self.logger.error(e)
self.logger.error(traceback.format_exc())
except Exception as e:
pass
# servicemanager.LogErrorMsg("{}".format(e))
#return some value other than 0 to os so that service knows to restart
self.logger.error("some exception in main")
exitcode = -1
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, ''))
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
self.logger.info("stopped with exit code {}".format(exitcode))
os._exit(exitcode)
def check_for_signals(self, timeout = 100):
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
def main(self):
# override in subclass
print("this is function main() that should be subclassed")
#time.sleep(1)
pass
if __name__ == '__main__':
handle(windows_daemon)
print("you should subclass windows_daemon from this module")
from windows_daemon import windows_daemon, handle
import time
import sys
import win32serviceutil
class New_service(windows_daemon):
# you can NET START/STOP the service by the following name
_svc_name_ = "NEW"
# this text shows up as the service name in the Service
# Control Manager (SCM)
_svc_display_name_ = "New service"
# this text shows up as the description in the SCM
_svc_description_ = "This service exists as a template for new services"
# override dependencies?
# _svc_deps_ = ["EventLog"]
def __init__(self, args):
print(super())
super().__init__(args)
def main(self):
time.sleep(10)
if __name__ == '__main__':
sys.frozen = 'windows_exe'
handle(New_service)
答案 0 :(得分:0)
显然,这条线引起了这个问题。我发现通过了解python调试模块(pdb)并使用它进行调查。
sys.frozen = 'windows_exe'
当我删除此行时, new_service.py 也会运行。希望这可以帮助将来的某个人。