你怎么运行Python脚本作为一个服务在窗口?
-
09-06-2019 - |
题
我素描的结构,为一套程序,分享的各种相互关联的对象存储在数据库。我想要一个计划作为一个服务提供了一个更高一级的接口,为操作这些目的,和其他程序访问的目的是通过该服务。
我目前正在针对蟒与Django框架,作为技术来实现,服务。我很确定我想如何agent Python计划在Linux。然而,这是一个可选择的规范的项目,该系统应支持Windows.我有点经验与Windows编程和没有经验,在所有与Windows服务。
是它能够运行一个Python程序作为Windows服务(i。e.自动运行,而不用户登录)? 我不一定必须实施这一部分,但我需要一个粗略的想法,它将如何做的,以便决定是否设计沿着这些路线。
编辑:谢谢你所有的答案迄今为止,它们是相当全面的。我想知道一件事: 怎么是Windows知道我的服务?我可以管理其与本机Windows公用事业? 什么是相当把启动/停止的脚本中/etc/init。d?
解决方案
是的,你可以。我这样做使用pythoncom库,包括与来 ActivePython 或可以被安装的 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服务。我想既然我可以通过选择向已安装的服务,我也可以同样选择我的蟒蛇可执行,并通过我的剧本作为一个选项。
我还没有尝试过这种解决方案,但是我会做这样的权利现在和更新这个帖子沿着该进程。我也有兴趣使用virtualenvs上窗户,使我能拿出一个教程或早或晚,并链接到它在这里。
有几个替代品用于安装服务几乎任何Windows可执行的。
方法1:使用instsrv和srvany从rktools.exe
为Windows服务器或Windows服务器2003年(与WinXP太), Windows服务器2003年资源工具包的工具 涉及与公用事业中可以使用串联,为此,所谓 instsrv.exe 和 srvany.exe.看看这微软KB的文章 KB137890 详细信息关于如何使用这些工具.
为Windows服务器,是一个伟大的友好的用户包装这些公用事业命名恰当地"任何服务,安装".
方法2:使用ServiceInstaller for Windows NT
还有另一种替代使用 ServiceInstaller for Windows NT (下载,能够在这里)与 蟒指示.相反的名称,它适用Windows2000和Windows XP。这里有一些说明如何安装python脚本作为一个服务。
安装Python脚本
运行ServiceInstaller创建一个新的 服务。(在这个例子,它是 假设蟒是安装在 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服务。
之后我最初的答案,我注意到有密切相关的问已经张贴在如此。参见:
最简单的方式实现这一点是使用当地的命令sc.exe:
sc create PythonApp binPath= "C:\Python34\Python.exe --C:\tmp\pythonscript.py"
参考文献:
最简单的方法是使用: NSSM-非吸吮服务管理:
1-作下载 https://nssm.cc/download
2-安装python程序作为一个服务:赢得迅速作的管理
c:>nssm.exe 安装WinService
3-在NSSMs控制台:
路径:C:\Python27\Python27.exe
启动目录:C:\Python27
参数:c:\WinService.py
4-检查创造了服务的服务。msc
一步一步解释如何使它的工作:
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"显示名称="TestService"开始=auto
第一个参数的 binpath 是的 路径python.exe
第二个论点的 binpath 是 路径的python文件 我们已经创造了
不小姐,你应该把一个空间,以后每隔"="标志。
然后如果一切都是好的,你应该看看
[SC]CreateService成功
现在你python服务是安装windows服务。你可以看到它在服务管理和注册表下:
此系统\CurrentControlSet\服务 estService
3-好的现在。你可以开始你的服务对服务的管理。
你可以执行的每一python文件,该文件提供这种服务的骨架。
我开始举办为服务 pywin32.
一切都很好但我遇到了问题的服务未能开始30秒内(默认timeout for 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,因为它是提议 在这个答案.这是非常容易迁移。
所接受的回答使用 win32serviceutil
工作但是是复杂的,使得调试和改变难。它是 远 更易于使用NSSM(非吸吮服务经理).你写和舒适的调试一个正常的蟒蛇的程序和时最后工作使用NSSM安装一个服务,在不到一分钟:
从提升(管理)命令提示你跑 nssm.exe install NameOfYourService
和你填补这些选项:
- 路径:(的的路径python.exe 例如
C:\Python27\Python.exe
) - 参数:(道路向python脚本,例如
c:\path\to\program.py
)
顺便说一句,如果您的程序印有用的消息,你要保持在一个日志文件NSSM也可以处理这个和更多的对你。
任何人谁想要建立的服务在VENV或Pycharm!!!!!!!
在阅读所有anwsers,并创建一些脚本,如果可以运行 python service.py install
和 python service.py debug
, 但 python service.py start
没有响应。
也许这是造成venv问题,因为windows服务开始你的服务exec PROJECT\venv\Lib\site-packages\win32\pythonservice.exe
.
你可以使用 powershell
或 cmd
来测试你的服务,以找到更多的错误的详细信息。
PS C:\Users\oraant> E:
PS E:\> cd \Software\PythonService\venv\Lib\site-packages\win32
PS E:\Software\PythonService\venv\Lib\site-packages\win32> .\pythonservice.exe -debug ttttt
Debugging service ttttt - press Ctrl+C to stop.
Error 0xC0000004 - Python could not import the service's module
Traceback (most recent call last):
File "E:\Software\PythonService\my_service.py", line 2, in <module>
import win32serviceutil
ModuleNotFoundError: No module named 'win32serviceutil'
(null): (null)
如果你获得一些错误喜欢我,然后你可以查我的回答另一个问题,我修好它和我的代码 在这里,.
nssm在python3+
(I转化我.py文件。exe与pyinstaller)
nssm:正如之前所说
- 运行nssm安装{服务名称}
在NSSMs控制台:
路径: path o\your\program.exe
启动目录: path o\你\#相同的路径,但是,如果没有你program.exe
参数:空
pysc: 业务控制的管理上的蟒蛇
例脚本,作为一个服务 采取从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