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

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

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

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


当前回答

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

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

引用:

https://technet.microsoft.com/en-us/library/cc990289 (v = ws.11) . aspx 当用sc.exe创建服务时,如何传递上下文参数?

其他回答

虽然我在几周前对所选的答案进行了投票,但与此同时,我在这个话题上挣扎了很多。感觉使用特殊的Python安装并使用特殊的模块将脚本作为服务运行是一种错误的方式。可移植性如何?

我偶然发现了很棒的非吸吮服务管理器,它让处理Windows服务变得非常简单和理智。我想既然我可以将选项传递给已安装的服务,那么我也可以选择我的Python可执行文件并将脚本作为一个选项传递。

我还没有尝试过这个解决方案,但我会马上尝试,并在此过程中更新这篇文章。我也对在Windows上使用virtualenvs感兴趣,所以我可能迟早会想出一个教程,并链接到这里。

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

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

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

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

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

使用win32serviceutil的公认答案是可行的,但它很复杂,使调试和更改更加困难。使用NSSM(非吸吮服务管理器)要容易得多。你编写并轻松调试一个普通的python程序,当它最终工作时,你使用NSSM在不到一分钟的时间内将其安装为服务:

在一个提升的(管理)命令提示符中,运行nssm.exe安装NameOfYourService并填写以下选项:

path:(python.exe的路径,例如C:\Python27\ python.exe) 参数:(python脚本的路径,例如c:\path\to\program.py)

顺便说一下,如果您的程序打印了想要保存在日志文件中的有用消息,那么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

一步一步地解释如何使它工作:

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)

在这一步,我们应该注册我们的服务。

以管理员身份运行命令提示符,输入as:

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

binpath的第一个参数是python.exe的路径

binpath的第二个参数是我们已经创建的python文件的路径

不要忘记在每个“=”号后面加一个空格。

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

[SC] CreateService SUCCESS . [SC

现在你的python服务已经被安装为windows服务了。你可以在服务管理器和注册表中看到它:

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ \ TestService服务

3-好了。您可以在服务管理器上启动服务。

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