【问题标题】:Python 3 Windows Service starts only in debug modePython 3 Windows 服务仅在调试模式下启动
【发布时间】:2017-03-04 18:27:29
【问题描述】:

我首先在this post 中发布了一个答案,但它不符合论坛标准。我希望这次回答符合论坛标准。这段代码应该更清晰易读。

在 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 时,提示说服务已安装(但日志文件中没有写入任何内容)。如果我尝试启动该服务,我会收到 Service Error: 1 - More info NET HELPMSG 3547 ,这并没有说明该错误。如果我运行python MyWindowsService.py debug,程序运行得很好(日志文件被写入),但我仍然无法控制服务:如果我打开另一个提示并尝试停止/启动服务,我仍然得到结果与上述相同。

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

我已经检查了网络上的多种解决方案和解决方法,但没有找到合适的。我错过了什么?

【问题讨论】:

  • 尝试使用sc start ServiceName 启动服务。这可能会提供更多信息。另外,使用命令sc qc ServiceName 查询配置。这应该显示“PythonService.exe”的完全限定路径。检查是否可以在命令提示符下运行它。如果没有,请确保将“python36.dll”、“vcruntime140.dll”和“pywintypes36.dll”符号链接到具有 PythonService.exe 的目录;或符号链接到 System32 目录;或者这些 DLL 的目录在系统中(不是用户)Path
  • 嗨 eryksun,感谢您的关注。
  • 我检查了你提到的 dll 并将它们的目录添加到系统路径 - 没有任何改变。 sc start ServiceName 返回STATUS 2 START_PENDING (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN) 我还在系统路径中添加了“PythonService.exe”路径 - 以防万一,但同样没有发生任何事情。
  • 这很正常。跟进sc query ServiceName 以查看当前状态。然后用sc stop ServiceName 停止它。
  • sc query ServiceName 返回STATUS: 1 STOPPED, WIN32_EXIT_CODE : 1066 sc stop ServiceName 返回FAILED 1062: Service not started

标签: python windows python-3.x debugging service


【解决方案1】:

正如 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。希望这可以帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-28
    • 1970-01-01
    相关资源
    最近更新 更多