Python 3 Windows Service仅在调试模式下启动

问题描述:

我第一次在this post中发布了答案,但它不符合论坛标准。我希望这次的答案符合论坛标准。此代码应该更清晰易读。Python 3 Windows Service仅在调试模式下启动

在Python 3+我有用来构建一个Windows服务下面的类(什么都不做,只是写入日志文件):

#MyWindowsService.py 
import win32serviceutil 
import servicemanager 
import win32service 
import win32event 
import sys 
import logging 
import win32api 


class MyWindowsService(win32serviceutil.ServiceFramework): 
    _svc_name_   = 'ServiceName' 
    _svc_display_name_ = 'Service Display Name' 
    _svc_description_ = 'Service Full Description' 
    logging.basicConfig(
     filename = 'c:\\Temp\\{}.log'.format(_svc_name_), 
     level  = logging.DEBUG, 
     format  = '%(levelname)-7.7s @ %(asctime)s: %(message)s' 
    ) 

    def __init__(self, *args): 
     self.log('Initializing service {}'.format(self._svc_name_)) 
     win32serviceutil.ServiceFramework.__init__(self, *args) 
     self.stop_event = win32event.CreateEvent(None, 0, 0, None) 

    def SvcDoRun(self): 
     self.ReportServiceStatus(win32service.SERVICE_START_PENDING) 
     try: 
      self.log('START: Service start') 
      self.ReportServiceStatus(win32service.SERVICE_RUNNING) 
      self.start() 
      win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE) 
     except Exception as e: 
      self.log('Exception: {}'.format(e)) 
      self.SvcStop() 

    def SvcStop(self): 
     self.log('STOP: Service stopping...') 
     self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 
     self.stop() 
     win32event.SetEvent(self.stop_event) 
     self.ReportServiceStatus(win32service.SERVICE_STOPPED) 

    def log(self, msg): 
     servicemanager.LogInfoMsg(str(msg)) #system log 
     logging.info(str(msg))    #text log 

    def start(self): 
     self.runflag = True 
     while self.runflag: 
      win32api.Sleep((2*1000), True) 
      self.log('Service alive') 
    def stop(self): 
     self.runflag = False 
     self.log('Stop received') 




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

在我使用日志文件检查脚本如果它工作正常。我在Windows 7上运行python3.6(也尝试使用python3.4),并且遇到以下问题。当我运行python MyWindowsService.py install时,提示说服务已安装(但没有任何内容写入日志文件)。如果我尝试启动该服务,则会收到服务错误:1 - 更多信息NET HELPMSG 3547,对此错误没有太多说明。如果我运行python MyWindowsService.py debug,程序运行得很好(写入日志文件),但仍然无法控制服务:如果我打开另一个提示并尝试停止/启动服务,我仍然得到相同的结果如上所述。

我也尝试在init函数中插入一些调试代码,当我运行python MyWindowsService.py安装它似乎没有被调用。可能吗?

我已经检查了多个解决方案和围绕网络的解决方法,但我没有找到任何合适的东西。我错过了什么?

+0

尝试使用'sc start ServiceName'开始服务。这可能提供更多信息。另外,使用命令“sc qc ServiceName”查询配置。这应该显示“PythonService.exe”的完整路径。检查是否可以在命令提示符下运行它。如果没有,请确保“python36.dll”,“vcruntime140。dll“和”pywintypes36.dll“或者符号链接到具有PythonService.exe的目录;或者符号链接到System32目录;或者具有这些DLL的目录在系统中(而不是用户)”路径“ – eryksun

+0

您好eryksun,感谢您的关注 – jekbau

+0

我检查了您提到的dll,并将其目录添加到了系统路径中 - 没有任何更改 sc start ServiceName'返回STATUS 2 START_PENDING(NOT_STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)' 我还在系统路径中添加了“PythonService.exe”路径 - 以防万一,但是没有发生任何事情 – jekbau

正如eriksun在第一篇文章的评论中指出的那样,问题出自python脚本的位置,这是在映射有UNC路径的驱动器中 - 我正在使用虚拟机。将python脚本移到与python安装相同的驱动器中,完成了这项工作。 概括起来以备将来使用,如果服务无法启动,你可以肯定你的代码,这些都是有益的行动,试图解决您的问题:

  • 使用sc start ServiceNamesc query ServiceNamesc stop ServiceName得到有关该服务的信息。
  • 检查您的文件是在物理驱动器还是在UNC映射的驱动器中。如果后者尝试使用UNC路径运行脚本(例如python \\Server\share\python\your-folder\script.py)或将脚本与Python安装
  • 相同的驱动器中移动,请确保“python36.dll”,“vcruntime140.dll”和“pywintypes36 .dll“要么符号链接到具有PythonService.exe的目录;或符号链接到System32目录;或与这些DLL的目录是在系统中(而非用户)路径
  • 检查系统命令reg query HKLM\System\CurrentControlSet\Services\your_service_name /s注册以获取有关脚本的详细信息

请随时来完成,变更,修改最后这样对于像我这样的人遇到这个问题可以是有用的。

编辑:还有一件事......我的项目被认为实际上与网络文件夹(和UNC映射的驱动器)工作,并且它失败时,我试图使其作为服务运行。我用来使其工作的一个非常有用(节省时间)的资源是我在this post中找到的SysinternalsSuite by Mark Russinovich。希望这可以帮助。