【问题标题】:Problems with converting a Python script into a Windows service将 Python 脚本转换为 Windows 服务的问题
【发布时间】:2017-07-03 17:37:08
【问题描述】:

我已经有一个连续运行的 python 脚本。与此非常相似:https://github.com/walchko/Black-Hat-Python/blob/master/BHP-Code/Chapter10/file_monitor.py

类似于,当它作为脚本运行时,它会打开一个 CMD,当事情发生时显示一些数据 - 它不是用户可交互的,因此它不是强制性的(以防万一有人希望指出 Windows 服务不能有接口)

我已尝试将其转换为服务。它启动了几分之一秒,然后自动停止。当尝试通过 services.msc(而不是 python script.py start)启动它时,它根本没有启动,Windows 错误显示类似:“本地计算机上的服务启动然后停止”这听起来就像发生了什么,如果我尝试从论点开始。

我尝试修改脚本以允许它作为服务运行 - 添加我在此处找到的骨架:Is it possible to run a Python script as a service in Windows? If possible, how?

我也尝试过获取上面的骨架脚本,并尝试通过以下示例使其运行其他脚本:What is the best way to call a Python script from another Python script?

有谁知道将上面的脚本作为服务运行的最佳做法是什么?

谢谢!

【问题讨论】:

    标签: python windows-services


    【解决方案1】:

    已编辑

    "...服务可以在电脑开机时自动启动,可以 暂停并重新启动,并且不显示任何用户界面。” ~Introduction to Windows Service Applications

    Windows 服务需要实现才能使特定接口可用:

    因此您需要通过 Python 访问 Windows API:

    你可以看到example code,来自Python Programming On Win32,其中第18章服务(ch18_services文件夹)包含一个示例(SmallestService.py),展示了用Python编写的最小可能的服务:

    # SmallestService.py
    # 
    # A sample demonstrating the smallest possible service written in Python.
    
    import win32serviceutil
    import win32service
    import win32event
    
    class SmallestPythonService(win32serviceutil.ServiceFramework):
        _svc_name_ = "SmallestPythonService"
        _svc_display_name_ = "The smallest possible Python Service"
        def __init__(self, args):
            win32serviceutil.ServiceFramework.__init__(self, args)
            # Create an event which we will use to wait on.
            # The "service stop" request will set this event.
            self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
    
        def SvcStop(self):
            # Before we do anything, tell the SCM we are starting the stop process.
            self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
            # And set my event.
            win32event.SetEvent(self.hWaitStop)
    
        def SvcDoRun(self):
            # We do nothing other than wait to be stopped!
            win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
    
    if __name__=='__main__':
        win32serviceutil.HandleCommandLine(SmallestPythonService)
    

    您可能需要在此处为​​您的特定 python 环境下载适当的 pywin32 轮: http://www.lfd.uci.edu/~gohlke/pythonlibs/#pywin32

    还有install它(系统范围,来自管理员 cmd 提示符):

    > cd \program files\python<ver>\scripts
    > pip install \path\to\pywin32‑221‑cp<ver>‑cp<ver>m‑win_<arch>.whl
    

    或安装它(每个用户,从常规 cmd 提示符):

    > cd \program files\python<ver>\scripts
    > pip install --user \path\to\pywin32‑221‑cp<ver>‑cp<ver>m‑win_<arch>.whl
    

    一定要适当地替换&lt;ver&gt;&lt;arch&gt;的出现。

    【讨论】:

    • 感谢您的信息!如果我想让服务运行我的其他脚本,我的代码应该在哪里以及如何显示?我应该把类似 subprocess.call("script.py") 的东西放在 win32serviceutil.HandleCommandLine(SmallestPythonService) 下吗?
    • 尝试从 SvcDoRun() 函数内部启动您的脚本。
    • 我接受了你的回答,因为它有点工作。服务正在安装,脚本开始在我使用“python script.py install”命令的同一 CMD 中运行。但它还没有开始,只有当我打开那个 CMD 窗口时它才会起作用。我得到这个:“实例的 SvcRun() 方法失败
    • 您还需要适当调整__init__SvcStop()内部的代码;请记住,这是最小的,因此您可能需要在现有函数中添加额外的函数或更多代码。
    猜你喜欢
    • 2016-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    相关资源
    最近更新 更多