编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

python散装笔记——169: 使用Python创建Windows服务

wxchong 2025-03-10 21:17:03 开源技术 19 ℃ 0 评论

在Windows中,没有用户界面的后台进程被称为服务。这些服务可以通过标准的Windows控制方式(如命令提示符、PowerShell或任务管理器中的服务选项卡)进行控制(启动、停止等)。一个很好的例子可能是提供网络服务的应用程序,例如Web应用程序,或者是一个执行各种后台归档任务的备份应用程序。有几种方法可以在Windows中将Python应用程序创建并安装为服务。

1: 可以作为服务运行的Python脚本

本示例中使用的模块是pywin32(Python for Windows扩展)的一部分。根据你的Python安装方式,你可能需要单独安装它。

 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()函数中。

你还需要将此服务安装为服务。目前,最好的解决方案似乎是使用Nonsucking Service Manager。这允许你安装服务,并提供一个GUI来配置服务执行的命令行。对于Python,你可以这样做,这将一次性创建服务:

 nssm install MyServiceName c:\python27\python.exe c:\temp\myscript.py

其中myscript.py是上面的样板脚本,修改为在main()函数中调用你的应用程序脚本或代码。注意,服务不会直接运行Python脚本,它运行Python解释器,并将主脚本作为命令行参数传递给它。

或者,你可以使用Windows Server Resource Kit中为你的操作系统版本提供的工具来创建服务。

2: 作为服务运行Flask Web应用程序

这是通用示例的一个变体。你只需要导入你的应用程序脚本,并在服务的main()函数中调用它的run()方法。在这个例子中,我们还使用了multiprocessing模块,因为访问WSGIRequestHandler时存在问题。

 import win32serviceutil
 import win32service
 import win32event
 import servicemanager
 from multiprocessing import Process
 
 from app import app
 
 class Service(win32serviceutil.ServiceFramework):
   _svc_name_ = "TestService"
   _svc_display_name_ = "Test Service"
   _svc_description_ = "Tests Python service framework by receiving and echoing messages over a named pipe"
 
   def __init__(self, *args):
     super().__init__(*args)
 
   def SvcStop(self):
     self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
     self.process.terminate()
     self.ReportServiceStatus(win32service.SERVICE_STOPPED)
 
   def SvcDoRun(self):
     self.process = Process(target=self.main)
     self.process.start()
     self.process.run()
 
   def main(self):
     app.run()
 
 if __name__ == '__main__':
   win32serviceutil.HandleCommandLine(Service)

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表