我正在为一组共享存储在数据库中的各种相关对象的程序绘制体系结构草图。我希望其中一个程序充当服务,为这些对象上的操作提供更高级别的接口,而其他程序通过该服务访问对象。

我目前的目标是将Python和Django框架作为实现该服务的技术。我很确定我知道如何在Linux中守护Python程序。但是,系统应该支持Windows,这是一个可选的规格项。我几乎没有Windows编程经验,对Windows服务也没有任何经验。

是否有可能运行Python程序作为Windows服务(即自动运行,无需用户登录)?我不一定要实现这一部分,但我需要一个大致的想法,以便决定是否沿着这些路线进行设计。

编辑:谢谢你到目前为止所有的回答,他们是相当全面的。我还想知道一件事:Windows是如何感知我的服务的?我可以使用本机Windows实用程序管理它吗?在/etc/init.d中放置启动/停止脚本的等效内容是什么?


当前回答

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

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

错误1053:服务没有及时响应启动或控制请求。

错误7009:等待<ServiceName>服务连接的超时(30000毫秒)。

我与pywin进行了大量的斗争,但最终使用了这个答案中提出的NSSM。移居到那里很容易。

其他回答

pysc: Python上的服务控制管理器

作为从pythonhosted.org获取的服务运行的示例脚本:

from xmlrpc.server import SimpleXMLRPCServer from pysc import event_stop class TestServer: def echo(self, msg): return msg if __name__ == '__main__': server = SimpleXMLRPCServer(('127.0.0.1', 9001)) @event_stop def stop(): server.server_close() server.register_instance(TestServer()) server.serve_forever() Create and start service import os import sys from xmlrpc.client import ServerProxy import pysc if __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')) Stop and delete service import pysc service_name = 'test_xmlrpc_server' pysc.stop(service_name) pysc.delete(service_name)

pip install pysc

实际上,可以将任何Windows可执行文件安装为服务。

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

对于Windows Home Server或Windows Server 2003(也适用于WinXP), Windows Server 2003资源工具包工具附带了可以同时使用的实用程序,称为instsrv.exe和srvany.exe。有关如何使用这些util的详细信息,请参阅Microsoft KB文章KB137890。

对于Windows Home Server,这些实用程序有一个非常友好的包装,叫做“任何服务安装程序”。

方法二:使用ServiceInstaller for Windows NT

还有另一种替代方案,使用ServiceInstaller for Windows NT(可在这里下载),并提供python指令。与名字相反,它也适用于Windows 2000和Windows XP。下面是一些关于如何将python脚本作为服务安装的说明。

Installing a Python script Run ServiceInstaller to create a new service. (In this example, it is assumed that python is installed at c:\python25) Service Name : PythonTest Display Name : PythonTest Startup : Manual (or whatever you like) Dependencies : (Leave blank or fill to fit your needs) Executable : c:\python25\python.exe Arguments : c:\path_to_your_python_script\test.py Working Directory : c:\path_to_your_python_script After installing, open the Control Panel's Services applet, select and start the PythonTest service.

在我最初的回答之后,我注意到SO上已经贴出了与之密切相关的问答。参见:

我可以将Python脚本作为服务运行吗(在Windows中)?如何?

如何让Windows知道我用Python编写的服务?

是的,你可以。我使用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方法中设置的标志可能会中断这种循环

这并没有回答最初的问题,但可能会帮助其他想要在Windows启动时自动启动Python脚本的人: 看看Windows任务调度程序,如果你只是想在启动后启动一个脚本,而不需要Windows服务的所有服务功能,它会更容易。

创建一个新任务,选择“At startup”作为触发器,选择“Start program”作为动作,程序为“C:\Python39\python.exe”(或任何python.exe所在的位置),脚本的完整路径(“C:…\my_dir\xyz.py”)作为参数(如果路径包含空格,则可以使用“”)。 你也可以选择你的脚本的路径(没有.py文件,例如。"C:…\my_dir")如果你在你的脚本中使用相对路径,例如日志。

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

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

错误1053:服务没有及时响应启动或控制请求。

错误7009:等待<ServiceName>服务连接的超时(30000毫秒)。

我与pywin进行了大量的斗争,但最终使用了这个答案中提出的NSSM。移居到那里很容易。