是否有可能在Windows中作为服务运行Python脚本? 如果可能,如何?

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

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

是否有可能运行一个Python程序作为Windows服务(即自动运行,而无需用户登录)? 我不一定要实现这个部分,但是我需要一个粗略的想法来决定是否按照这些方式来设计。

编辑:感谢迄今为止所有的答案,他们是相当全面的。 我想知道一件事情: Windows如何意识到我的服务? 我可以使用本地Windows实用程序来管理它吗? 在/etc/init.d中放入启动/停止脚本的等效功能是什么?

是的你可以。 我使用的是包含在ActivePython中的pythoncom库,或者可以用pywin32 (Python for Windows extensions)来安装它。

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

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方法中设置的标志而中断

尽管我在几周前提出了选择的答案,但同时我也在这个问题上挣扎了很多。 感觉就像有一个特殊的Python安装和使用特殊的模块来运行一个脚本作为一个服务是错误的方式。 那么可移植性呢?

我偶然发现了非常吸引人的服务管理器 ,这使得处理Windows服务变得非常简单和理智。 我想,因为我可以将选项传递给已安装的服务,所以我可以选择我的Python可执行文件并将脚本作为选项传递给我们。

我还没有尝试过这个解决方案,但我现在要做,并沿着这个过程更新这个帖子。 我也有兴趣在Windows上使用virtualenvs,所以我可能迟早会拿出一个教程,并链接到这里。

几乎所有的Windows可执行文件都可以作为服务来安装。

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

对于Windows Home Server或Windows Server 2003(也适用于WinXP), Windows Server 2003资源工具包工具随附可用于此目的的实用程序,称为instsrv.exesrvany.exe 。 有关如何使用这些使用情况的详细信息,请参阅此Microsoft知识库文章KB137890 。

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

方法2:为Windows NT使用ServiceInstaller

还有另一种替代方法,使用Windows NT的ServiceInstaller ( 可以在这里下载 )使用python指令 。 与名称相反,它同时适用于Windows 2000和Windows XP。 以下是如何将python脚本作为服务安装的说明。

安装一个Python脚本

运行ServiceInstaller以创建一个新的服务。 (在这个例子中,假设python安装在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 

安装后,打开控制面板的服务小程序,选择并启动PythonTest服务。

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

我可以运行Python脚本作为服务(在Windows中)? 怎么样?

如何使Windows意识到我用Python编写的服务?

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

 sc create PythonApp binPath= "C:\Python34\Python.exe --C:\tmp\pythonscript.py" 
  1. https://technet.microsoft.com/en-us/library/cc990289(v=ws.11).aspx
  2. 使用sc.exe创建服务; 如何传递上下文参数

一步一步的解释如何使其工作:

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 – 在这一步,我们应该注册我们的服务。

管理员身份运行命令提示符并键入:

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

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

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

不要错过在每个“ = ”号后面应该放一个空格。

那么如果一切都好,你应该看看

[SC] CreateService SUCCESS

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

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

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

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

最简单的方法是使用: NSSM – Non-Sucking服务管理器:

1 – 在https://nssm.cc/download下载;

2 – 将python程序安装为服务:以管理员身份运行Win提示符

c:> nssm.exe安装WinService

3 – 在NSSM的控制台上:

路径:C:\ Python27 \ Python27.exe

启动目录:C:\ Python27

参数:c:\ WinService.py

4 – 检查services.msc上创建的服务

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() 

创建并启动服务

 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')) 

停止并删除服务

 import pysc service_name = 'test_xmlrpc_server' pysc.stop(service_name) pysc.delete(service_name) 
 pip install pysc