我正在为一组共享存储在数据库中的各种相关对象的程序绘制体系结构草图。我希望其中一个程序充当服务,为这些对象上的操作提供更高级别的接口,而其他程序通过该服务访问对象。
我目前的目标是将Python和Django框架作为实现该服务的技术。我很确定我知道如何在Linux中守护Python程序。但是,系统应该支持Windows,这是一个可选的规格项。我几乎没有Windows编程经验,对Windows服务也没有任何经验。
是否有可能运行Python程序作为Windows服务(即自动运行,无需用户登录)?我不一定要实现这一部分,但我需要一个大致的想法,以便决定是否沿着这些路线进行设计。
编辑:谢谢你到目前为止所有的回答,他们是相当全面的。我还想知道一件事:Windows是如何感知我的服务的?我可以使用本机Windows实用程序管理它吗?在/etc/init.d中放置启动/停止脚本的等效内容是什么?
是的,你可以。我使用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方法中设置的标志可能会中断这种循环
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
https://www.chrisumbel.com/article/windows_services_in_python
跟踪PySvc.py
更改DLL文件夹
我知道这很旧了,但我一直都困在这上面。对我来说,这个特定的问题是通过复制这个文件pywintypes36.dll解决的
号码
To -> Python36\Lib\site-packages\win32
setx /M PATH "%PATH%;C:\Users\user\AppData\Local\Programs\Python\Python38-32;C:\Users\user\AppData\Local\Programs\Python\Python38-32\Scripts;C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\pywin32_system32;C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\win32
将路径更改为python文件夹
cd C:\Users\user\AppData\Local\Programs\Python\ Python38-32
NET START PySvc
NET STOP PySvc
是的,你可以。我使用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方法中设置的标志可能会中断这种循环
一步一步地解释如何使它工作:
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文件。