文章目录
- 0 前言
- 1 代码框架
- 2 使用方式
- 3 遇到的问题和解决方案
0 前言
最近揽了一个小活,就是基于Python设计一个Windows Service程序,和一般应用不同的是,Service直接运行在后台,不会在运行时弹出黑框,因此在设计上和一般的程序有些微差别。因为之前从来没有做过这个,因此做个记录。
1 代码框架
使用Python写Windows Service,其代码的基本框架是固定的,这也大大方便降低了入门的难度。经过查找资料,加上自己的尝试,总结出如下代码基本结构。
import servicemanager
import sys
import win32event
import win32service
import win32serviceutilclass TestService(win32serviceutil.ServiceFramework):'''这里是一些服务的基本信息, 根据自己需要进行修改'''_svc_name_ = "TestService"_svc_display_name_ = "Test Service"_svc_description_ = "My service description"def __init__(self, args):''' 初始化函数, 服务启动时调用, 可以用来初始化一些变量'''win32serviceutil.ServiceFramework.__init__(self, args)self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)def SvcStop(self):'''停止函数, 服务停止时调用, 可以用来释放资源等操作'''self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)win32event.SetEvent(self.hWaitStop)def SvcDoRun(self):'''运行函数, 服务启动时调用, 可以在这里写你的代码, 注意要是一个死循环'''rc = Nonewhile rc != win32event.WAIT_OBJECT_0:############################################ 这里写你的代码###########################################with open('C:\\TestService.log', 'a') as f:f.write('test service running...\n')rc = win32event.WaitForSingleObject(self.hWaitStop, 5000)def other_function(self):'''其他函数, 可以用于写其他的代码,然后在主线程中调用'''passif __name__ == '__main__':'''服务入口函数, 不用修改'''if len(sys.argv) == 1:servicemanager.Initialize()servicemanager.PrepareToHostSingle(TestService)servicemanager.StartServiceCtrlDispatcher()else:win32serviceutil.HandleCommandLine(TestService)
2 使用方式
基于上述代码结构,接下来就可以根据自己需要实现的功能写代码了,和其他的开发方式没什么区别,也可以使用多线程。开发完成之后,接下来就是打包程序生成服务了,这里使用到的还是使用最为普遍的pyinstaller
模块,打包指令如下
pyinstaller -F --hidden-import=win32timezone .\<文件名>.py
这样就能得到一个执行程序,接下来还需要基于这个执行程序安装,运行,暂停,卸载服务等操作,基本指令如下所示。
# 安装服务
.\dist\<执行文件名>.exe install# 启动服务
.\dist\<执行文件名>.exe start# 停止服务
.\dist\<执行文件名>.exe stop# 卸载服务
.\dist\<执行文件名>.exe remove
到此,基本走完了开发流程,剩下的主要就是功能调试了,比较繁琐,不再赘述。
3 遇到的问题和解决方案
-
卸载再安装服务显示“指定的服务已标记为删除”
这是因为在调试过程中打开了服务那个窗口导致的,所以最简单的办法就是强制删除服务之后,重启终端,然后不再在调试过程中打开服务那个窗口,如果还不行,就重启电脑试试。实际上我的问题出在代码上面,因为我代码中服务执行部分有socket的accept函数,导致程序是堵塞执行的,所以实际上需要一定的时间这个服务也会自动删除。
-
Updating…