【问题标题】:CherryPy as a Windows Service - the exampleCherryPy 作为 Windows 服务 - 示例
【发布时间】:2014-09-09 09:42:37
【问题描述】:

我看到很多人都在为此苦苦挣扎——我也遇到了问题。如果有人可以帮助使 CherryPy 服务示例工作,那将是一个很大的帮助。解释这些问题将不胜感激。

有一个 CherryPy as a Windows Service 示例,位于:CherryPy Wiki。我正在努力让它发挥作用。这是我的代码:

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

import cherrypy
import win32serviceutil
import win32service
import win32event
import servicemanager

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

    def index(self):
        return "Hello world!"
    index.exposed = True


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

    _svc_name_ = "CherryPyService"
    _svc_display_name_ = "CherryPy Service"

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        # create an event that SvcDoRun can wait on and SvcStop
        # can set.
        self.stop_event = win32event.CreateEvent(None, 0, 0, None)

    def SvcDoRun(self):
        self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_,''))

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

        # in practice, you will want to specify a value for
        # log.error_file below or in your config file.  If you
        # use a config file, be sure to use an absolute path to
        # it, as you can't be assured what path your service
        # will run in.
        cherrypy.config.update({
            'global':{
                'engine.autoreload.on': False,
                'log.screen': False,
                'log.error_file': 'c:\\MG\\temp\\CherryPy_Sample_Service.log',
                'engine.SIGHUP': None,
                'engine.SIGTERM': None
                }
            })
        # set blocking=False so that start() does not block
        cherrypy.server.quickstart()
        cherrypy.engine.start(blocking=False)
        # now, block until our event is set...
        win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
        self.ReportServiceStatus(win32service.SERVICE_RUNNING)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        cherrypy.server.stop()
        win32event.SetEvent(self.stop_event)

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

以上内容与链接示例不同。我已经添加了

  • self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
  • self.ReportServiceStatus(win32service.SERVICE_RUNNING) 作为SvcDoRun 的第一个和最后一个语句
  • 'log.error_file': 'c:\\MG\\temp\\CherryPy_Sample_Service.log', 维基指示

重要提示:虽然可以使用控制台python cherrypy_sample_service.py install 安装服务,但不可能使用python cherrypy_sample_service.py start 命令启动它。这样做的原因是,以这种方式创建的服务将引用python 可执行文件,它不是作为服务设计的。

因此,为了进一步测试,我使用以下代码编译了代码:

from cx_Freeze import setup, Executable

exe = Executable(
    script='cherrypy_sample_service.py'
)


build_options = {'includes': ['cherrypy', 'win32serviceutil', 'win32service', 'win32event', 'servicemanager']}

setup(
        name = "CherryPy Sample Service",
        version = "0.1",
        service = ["cherrypy_sample_service.py"],
        options = {"build_exe" : build_options},
        executables = [exe])

在构建过程中,我收到以下警告:

Python27\App\lib\distutils\dist.py:267: UserWarning: Unknown distribution option: 'service'
warnings.warn(msg)

我已根据以下stack problem answer 添加了此选项。

现在我可以致电cherrypy_sample_service installcherrypy_sample_service removecherrypy_sample_service update。但是尝试运行服务(从服务或通过cherrypy_sample_service start)会导致以下错误:

Error starting service: The service did not respond to the start or control request in a timely fashion.

我被困住了。甚至没有创建日志文件。你能帮我让这个例子运行吗?我想如果我们可以解释并运行一个示例,这对于其他在相关问题上苦苦挣扎的人也很有用。谢谢!

【问题讨论】:

    标签: python windows service cherrypy


    【解决方案1】:

    我刚刚从您提到的 wiki 页面中获取了 3.1 的版本,它可以立即运行。 IE。它从命令行安装、启动和停止,就像从服务管理 GUI 启动和停止一样。

    """
    The most basic (working) CherryPy 3.1 Windows service possible.
    Requires Mark Hammond's pywin32 package.
    """
    
    import cherrypy
    import win32serviceutil
    import win32service
    
    class HelloWorld:
        """ Sample request handler class. """
    
        @cherrypy.expose
        def index(self):
            return "Hello world!"
    
    
    class MyService(win32serviceutil.ServiceFramework):
        """NT Service."""
    
        _svc_name_ = "CherryPyService"
        _svc_display_name_ = "CherryPy Service"
    
        def SvcDoRun(self):
            cherrypy.tree.mount(HelloWorld(), '/')
    
            # in practice, you will want to specify a value for
            # log.error_file below or in your config file.  If you
            # use a config file, be sure to use an absolute path to
            # it, as you can't be assured what path your service
            # will run in.
            cherrypy.config.update({
                'global':{
                    'log.screen': False,
                    'engine.autoreload.on': False,
                    'engine.SIGHUP': None,
                    'engine.SIGTERM': None
                    }
                })
    
            cherrypy.engine.start()
            cherrypy.engine.block()
    
        def SvcStop(self):
            self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
            cherrypy.engine.exit()
    
            self.ReportServiceStatus(win32service.SERVICE_STOPPED) 
            # very important for use with py2exe
            # otherwise the Service Controller never knows that it is stopped !
    
    if __name__ == '__main__':
        win32serviceutil.HandleCommandLine(MyService)
    

    测试环境为:XP SP3、Python 2.7.5、CherryPy 3.3,0、pywin32 218.4。

    调试提示

    无需构建二进制文件即可运行您的服务。当您从源代码安装 pywin32 服务时,它使用 %PYDIR%\Lib\site-packages\win32\pythonservice.exe 作为服务代理。 IE。所有服务都将其作为运行命令行,REG:\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CherryPyService\PythonClass 定义了服务的实际 Python 类。

    从命令行运行 pythonservice.exe 并确保它运行时没有错误 (1)。您可能还会注意到,有一个调试选项允许您将服务的 stdout 和 stderr 附加到终端 (2)。

    确保没有阻止pythonservice.exe 进行网络活动的防火墙软件。

    【讨论】:

    • 我仍然在苦苦挣扎,没有运气。我试过这个(只是一个没有cherrypy的简单服务):stackoverflow.com/questions/32404/…,它也不起作用。我正在使用 Win7(在不同的机器上)。我猜这是由于某些特权。
    【解决方案2】:

    我终于找到了解决方案 - 我已经下载并重新安装了 pywin32... 一切正常! :)

    一些最后的笔记:

    • 服务从编辑器启动正常 - 不需要编译。
    • 'log.error_file': 'c:\\somedir\cherypy_sample_service.log' 添加到cherrypy.config.update 有助于验证服务是否已启动和运行

    在尝试调试问题时,我发现一旦win32serviceutil.HandleCommandLine 调用StartService 并进入这部分代码:

        try:
            win32service.StartService(hs, args)
        finally:
            win32service.CloseServiceHandle(hs)
    

    我无法进入win32service.StartService。我无法找到该文件,这就是我重新安装 pywin32 的原因。

    我只能希望有一些错误消息 - 希望这对其他人有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-07
      • 2012-08-04
      • 1970-01-01
      • 2020-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多