首页 文章

如何在Windows中将Python脚本作为服务运行?

提问于
浏览
221

我正在绘制一组程序的架构,这些程序共享存储在数据库中的各种相互关联的对象 . 我希望其中一个程序充当服务,为这些对象的操作提供更高级别的接口,以及通过该服务访问对象的其他程序 .

我目前的目标是将Python和Django框架作为实现该服务的技术 . 我很确定我会想到如何在Linux中守护Python程序 . 但是,它是系统应支持Windows的可选规范项 . 我对Windows编程没什么经验,也没有Windows服务的经验 .

Is it possible to run a Python programs as a Windows service (i. e. run it automatically without user login)? 我不一定要实现这一部分,但我需要大致了解如何才能决定是否按照这些方式进行设计 .

编辑:感谢目前为止的所有答案,它们非常全面 . 我想知道一件事:Windows如何了解我的服务?我可以使用本机Windows实用程序进行管理吗?在/etc/init.d中放置一个启动/停止脚本相当于什么?

9 回答

  • 24

    pysc:Service Control Manager on Python

    作为服务运行的示例脚本taken from pythonhosted.org

    从xmlrpc.server导入SimpleXMLRPCServer

    来自pysc import event_stop

    类TestServer:

    def echo(self,msg):
    返回消息

    如果__name__ =='__ main__':
    server = SimpleXMLRPCServer(('127.0.0.1',9001))

    @event_stop
    def stop():
    server.server_close()

    server.register_instance(TESTSERVER())
    server.serve_forever()
    创建并启动服务导入操作系统
    导入系统
    来自xmlrpc.client导入ServerProxy

    进口pysc

    如果__name__ =='__ main__':
    service_name ='test_xmlrpc_server'
    script_path = os.path.join(
    os.path.dirname(__ file __),'xmlrpc_server.py'

    pysc.create(
    SERVICE_NAME = SERVICE_NAME,
    cmd = [sys.executable,script_path]

    pysc.start(SERVICE_NAME)

    client = ServerProxy('http://127.0.0.1:9001')
    print(client.echo('test scm'))
    停止并删除服务导入pysc

    service_name ='test_xmlrpc_server'

    pysc.stop(SERVICE_NAME)
    pysc.delete(SERVICE_NAME)

    pip install pysc
    
  • 18

    逐步说明如何使其工作:

    1-首先根据上面提到的基本骨架创建一个python文件 . 并将其保存到路径中,例如:“c:\ PythonFiles \ AppServerSvc.py”

    import win32serviceutil
    import win32service
    import win32event
    import servicemanager
    import socket
    
    
    class AppServerSvc (win32serviceutil.ServiceFramework):
        _svc_name_ = "TestService"
        _svc_display_name_ = "Test Service"
    
    
        def __init__(self,args):
            win32serviceutil.ServiceFramework.__init__(self,args)
            self.hWaitStop = win32event.CreateEvent(None,0,0,None)
            socket.setdefaulttimeout(60)
    
        def SvcStop(self):
            self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
            win32event.SetEvent(self.hWaitStop)
    
        def SvcDoRun(self):
            servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_,''))
            self.main()
    
        def main(self):
            # Your business logic or call to any class should be here
            # this time it creates a text.txt and writes Test Service in a daily manner 
            f = open('C:\\test.txt', 'a')
            rc = None
            while rc != win32event.WAIT_OBJECT_0:
                f.write('Test Service  \n')
                f.flush()
                # block for 24*60*60 seconds and wait for a stop event
                # it is used for a one-day loop
                rc = win32event.WaitForSingleObject(self.hWaitStop, 24 * 60 * 60 * 1000)
            f.write('shut down \n')
            f.close()
    
    if __name__ == '__main__':
        win32serviceutil.HandleCommandLine(AppServerSvc)
    

    2 - 在此步骤中,我们应该注册我们的服务 .

    将命令提示符运行为 administrator 并键入:

    sc create TestService binpath =“C:\ Python36 \ Python.exe c:\ PythonFiles \ AppServerSvc.py”DisplayName =“TestService”start = auto

    binpath 的第一个参数是 path of python.exe

    binpath 的第二个参数是我们已经创建的 the path of your python file

    不要错过你应该在每个“ = ”标志后放一个空格 .

    如果一切正常,你应该看到

    [SC] CreateService SUCCESS

    现在你的python服务现在作为windows服务安装 . 您可以在Service Manager和注册表中看到它:

    HKEY_LOCAL_MACHINE \系统\ CurrentControlSet \服务\ TestService的

    3-现在好 . 您可以在服务管理器上启动服务 .

    您可以执行提供此服务框架的每个python文件 .

  • 0

    最简单的方法是使用: NSSM - the Non-Sucking Service Manager:

    1 - make download on https://nssm.cc/download

    2 - install the python program as a service: Win prompt as admin

    c:> nssm.exe安装WinService

    3 - On NSSM´s console:

    路径:C:\ Python27 \ Python27.exe

    启动目录:C:\ Python27

    参数:c:\ WinService.py

    4 - check the created services on services.msc

  • 31

    虽然几个星期前我对所选择的答案进行了评价,但与此同时,我在这个主题上更加努力 . 感觉就像有一个特殊的Python安装并使用特殊模块来运行脚本作为服务只是错误的方式 . 便携性等等呢?

    我偶然发现了精彩的Non-sucking Service Manager,这使得处理Windows服务非常简单明了 . 我想,既然我可以将选项传递给已安装的服务,我也可以选择我的Python可执行文件并将我的脚本作为选项传递 .

    我还没有尝试过这个解决方案,但我现在会这样做,并在整个过程中更新这篇文章 . 我也有兴趣在Windows上使用virtualenvs,所以我迟早会提出一个教程并在这里链接到它 .

  • 1

    几乎任何Windows可执行文件都可以作为服务安装 .

    方法1:使用rktools.exe中的instsrv和srvany

    对于Windows Home Server或Windows Server 2003(也适用于WinXP),Windows Server 2003 Resource Kit Tools带有可以串联使用的实用程序,称为 instsrv.exesrvany.exe . 有关如何使用这些工具的详细信息,请参阅此Microsoft知识库文章KB137890 .

    对于Windows Home Server,这些实用程序有一个很好的用户友好包装,名为aptly“Any Service Installer” .

    方法2:使用ServiceInstaller for Windows NT

    使用带有python instructions availableServiceInstaller for Windows NTdownload-able here)还有另一种选择 . 与名称相反,它也适用于Windows 2000和Windows XP . 以下是有关如何将python脚本安装为服务的一些说明 .

    安装Python脚本运行ServiceInstaller创建一项新服务 . (在此示例中,假设python安装在c:\ python25)服务名称:PythonTest
    显示名称:PythonTest
    启动:手动(或任何你喜欢的)
    依赖关系:(留空或填写以满足您的需求)
    可执行文件:c:\ python25 \ python.exe
    参数:c:\ path_to_your_python_script \ test.py
    工作目录:c:\ path_to_your_python_script
    安装后,打开控制面板的服务小程序,选择并启动PythonTest服务 .

    在我最初的回答之后,我注意到已经在SO上发布了密切相关的问答 . 也可以看看:

    Can I run a Python script as a service (in Windows)? How?

    How do I make Windows aware of a service I have written in Python?

  • -2

    实现此目的的最简单方法是使用本机命令sc.exe:

    sc create PythonApp binPath= "C:\Python34\Python.exe --C:\tmp\pythonscript.py"
    
  • 13

    是的你可以 . 我使用ActivePython附带的pythoncom库或者可以使用pywin32(Python for Windows扩展)安装 .

    这是简单服务的基本框架:

    import win32serviceutil
    import win32service
    import win32event
    import servicemanager
    import socket
    
    
    class AppServerSvc (win32serviceutil.ServiceFramework):
        _svc_name_ = "TestService"
        _svc_display_name_ = "Test Service"
    
        def __init__(self,args):
            win32serviceutil.ServiceFramework.__init__(self,args)
            self.hWaitStop = win32event.CreateEvent(None,0,0,None)
            socket.setdefaulttimeout(60)
    
        def SvcStop(self):
            self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
            win32event.SetEvent(self.hWaitStop)
    
        def SvcDoRun(self):
            servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                                  servicemanager.PYS_SERVICE_STARTED,
                                  (self._svc_name_,''))
            self.main()
    
        def main(self):
            pass
    
    if __name__ == '__main__':
        win32serviceutil.HandleCommandLine(AppServerSvc)
    

    您的代码将进入 main() 方法 - 通常使用某种无限循环,可能会通过检查您在 SvcStop 方法中设置的标志来中断

  • 9

    使用 win32serviceutil 接受的答案有效,但很复杂,使调试和更改变得更难 . 这是 far 更容易使用NSSM(the Non-Sucking Service Manager) . 您编写并轻松调试正常的python程序,当它最终工作时,您使用NSSM在不到一分钟的时间内将其安装为服务:

    从提升(管理员)命令提示符运行 nssm.exe install NameOfYourService 并填写以下选项:

    • path :( python.exe的路径,例如 C:\Python27\Python.exe

    • Arguments :( python脚本的路径,例如 c:\path\to\program.py

    顺便说一句,如果你的程序打印出你想要保存在日志文件中的有用消息,NSSM也可以为你处理这个问题 .

  • 229

    我开始使用pywin32作为服务托管 .

    一切都很顺利,但我遇到了系统启动时服务无法在30秒内启动(Windows的默认超时)的问题 . 这对我来说至关重要,因为Windows启动是在一台物理机器上托管的多个虚拟机上同时发生的,并且IO负载非常大 . 错误消息是:

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

    Error 7009: Timeout (30000 milliseconds) waiting for the <ServiceName> service to connect.

    我和pywin进行了很多斗争,但最终使用了NSSM,因为它被提议in this answer . 迁移到它很容易 .

相关问题