国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Python寫WindowsService服務程序

2019-11-14 17:12:28
字體:
來源:轉載
供稿:網友

 

1.需求

為什么要開發一個windows服務呢?之前做一個程序,必須要讀取指定目錄文件License, 因為其他程序也在讀取這指定目錄的License文件,且License不同時會修改License的內容,
修改了License后導致我們的程序無法運行,所以想做個windows 的服務時時檢測這個License文件是否被修改,如果檢測到被修改就覆蓋該License。

 

2.依賴的第三方庫

必須要借助第三方模塊pywin32
下載地址: https://pypi.python.org/pypi/pywin32/214

 

3.實現過程

實例化win32serviceutil.ServiceFramework的時候,windows系統會自動調用SvcDoRun方法,
這個函數的執行不可以結束,因為結束就代表服務停止。所以當我們放自己的代碼在SvcDoRun函數中執行的時候,必須確保該函數不退出,類似與這樣的效果:

1 def SvcDoRun(self):2        while True:3             self._LicenseExist()4             time.sleep(2)

當停止服務的時候,系統會調用SvcDoStop函數,該函數通過設置標志位等方式讓SvcDoRun函數退出,就是正常的停止服務。
win32event.SetEvent(self.hWaitStop) 通過事件退出

服務操作命令:

 1 #1.安裝服務 2  3 python PythonService.py install 4  5 #2.讓服務自動啟動 6  7 python PythonService.py --startup auto install  8  9 #3.啟動服務10 11 python PythonService.py start12 13 #4.重啟服務14 15 python PythonService.py restart16 17 #5.停止服務18 19 python PythonService.py stop20 21 #6.刪除/卸載服務22 23 python PythonService.py remove

 

4.完整代碼:

 1 # -*- coding: UTF8 -*- 2 #  3 import win32serviceutil  4 import win32service  5 import win32event 6 import winerror 7 import servicemanager 8 import os, sys, time 9 10 class PythonService(win32serviceutil.ServiceFramework): 11 12     _svc_name_ = "ALicense"   #  服務名13     _svc_display_name_ = "ALicense Is Exist "   # 服務在windows系統中顯示的名稱14     _svc_description_ = "ALicense  Is Exist License windows"   #服務的描述15 16     def __init__(self, args): 17         win32serviceutil.ServiceFramework.__init__(self, args) 18         self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)19         self.License = self._LicenseExist()20         self.run = True21         22     def _LicenseExist(self):23         is_exist=os.path.exists('C:/License.dat')24         string_key='d8838bccad0c19e847b9e73f4432b951b6f035fd8c19f5474e30db5a0e4fa4c99b57c01af79161850b95d3f99a6b0b6074f18224ec7c44f28bc243be06f8f2b96e370f5ca724c01f1bd0e289afdd9eeef7e33d42a5113ddd4818a47b33449487baec2099a50d5e3dde32bdf66d979982a68d0d60a1200990ebf8a4827b7db3d1e83f9ad9d9946267fe830c48bbe025a5ebb99b85c7f1cf93de2beb22c8e9766e5ef526242b01f5251d8a768780026add2d2d8fb9ffccb86f8779221b01d206e586d96b83839b30006910a4bca6438fb5d5b2900431f8ecab50a9f18d0e7e8abec7b212fdc9ab667f08dd3eef14ecbdb24910466f45be92d0a085ff81d7362b828847c29be579942b63b9eb26b2441b5ef20f5a012431d263ded3f5fe434111b833612464bf4df18ae06c536b6895d240387774c3b438d5f0745c7a0d3ce963e82fc8df603f6fa526e8bd1fc51e2509e0840f3bbbde7bc3fec9e837b5aa744a9ae4449c974e26d787e475f73dbc3ee9c73cc258f38b79c413453fd4fe732bed57ba9d0312d2bcaf333a5c82d92a269a7ccaf27273a178feb95028f8f0805675a6199abbd8b47756b4543269a35025438794cd32410ac19c77526c4b94b93d091069056df1dda0f49298d753a317850c7104f94067ac9cc4d5b3d377f10627d21c12a4c066347eb05370fbe9e0658c1ec1803d43ed71509f5cdb25d60f505ef7527c405d3ea05bb381436dd3622484a1ff7263e4d93f275493332af3f77d28a13a0fa0eb810b7d25a378f6b8313ab3bcb44131ca3500670b0321aa95b077cef85d348e13315c2d2d42795e41569162986755709d099b59ee320e6caf422497234251d07d697bb3f3e5ad6d15d80fd85da016e7075bf84522aa6339e8b66ecd4b71d02fd01f4f57a0147ceaddbf9e5f32e7ec60ae35ff73d2f386d9d0133cb697731773b55fc2615c584e9f4013253d3fc53fa13a9e982a2493e1145861759c30cf9064d333bb184e378b52e7dd8bbbd0c17774549fabb44014dab2e0a903c53d0da1c9d3a223c69f3b9bcc7925ba21a464fc9fa43e20574ffedb7a27f2cd7ae7b6b46c5cb4e0b176ece7d59ff199b74b3436ead185df5c79d74b35d644bb02315130131772db21fcd1d535014b10c4cbbb8e1f847cd00be52992ab94a7b5a7b1c27d87abe3fc605972ceb3463a07924c816a04642adcabbc7b18a40a24a3af217d0390c1102cb5b4573b1816c76667f50d33631a97e986255644e8e0c26d63cd1f29f501ff51673509822c1bf8158ceee752024dcbe0e24941803ebd8afc0bded3598012ba5431060f0db7fad7fd4960972da9a6cfaa0850c43470498236ef7b22fbf79d491e054cf142815e6c04e573a52e22ccaa2d406167c6442db40456cd93752349b2968132388b51edbe13aa349abc34696453d1a4b39f8311284f8afbae'25         if is_exist:26             for line in open("C:/License.dat"):27                 if line!=string_key:28                     self.writer(string_key)29         else:30             self.writer(string_key)31     # 寫入License        32     def writer(self, string_key):33         f=open('C:/License.dat','w')34         f.write(string_key)35         f.close()36         37     def SvcDoRun(self):38         while self.run:39             # 已經運行40             self._LicenseExist()41             time.sleep(2)   #推遲調用線程的運行2秒42                 43     def SvcStop(self): 44         # 服務已經停止45         self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 46         win32event.SetEvent(self.hWaitStop) 47         self.run = False48 49 if __name__=='__main__':50     if len(sys.argv) == 1:51         try:52             evtsrc_dll = os.path.abspath(servicemanager.__file__)53             servicemanager.PRepareToHostSingle(PythonService)54             servicemanager.Initialize('PythonService', evtsrc_dll)55             servicemanager.StartServiceCtrlDispatcher()56         except win32service.error, details:57             if details[0] == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:58                 win32serviceutil.usage()59     else:60         win32serviceutil.HandleCommandLine(PythonService)

 

5.效果與問題

當直接運行py文件訪問是可以添加服務,且服務也可運行,但是使用pyinstaller打包exe后程序就不能正常執行,
提示:錯誤1053 服務沒有及時相應啟動或控制請求

google 后找到解決方法,
原理我也不是很懂,貌似是要在實例化windows服務類時候,監控服務調度

 1     if len(sys.argv) == 1: 2         try: 3             evtsrc_dll = os.path.abspath(servicemanager.__file__) 4             servicemanager.PrepareToHostSingle(PythonService) 5             servicemanager.Initialize('PythonService', evtsrc_dll) 6             servicemanager.StartServiceCtrlDispatcher() 7         except win32service.error, details: 8             if details[0] == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: 9                 win32serviceutil.usage()10     else:11         win32serviceutil.HandleCommandLine(PythonService)

pyinstaller 打包為控制臺文件

1 if __name__ == '__main__':2     from PyInstaller.main import run3     params=['windows_services_in_python.py', '-F', '-c', '--icon=favicon.ico']4     run(params)

打包后CMD到改目錄:

放行殺毒軟件攔截

 

 

6.管理window服務操作

完整代碼:

  1 #!/usr/bin/env python  2 # -*- coding: UTF8 -*-  3 #  4 import win32service  5 import win32con  6 import time, sys  7 import datetime  8 reload(sys)  9 sys.setdefaultencoding("utf8") 10 class ServiceManager(object): 11     """管理window服務""" 12  13     def __init__(self, name): 14         """ 15         name: 服務的名稱 16         """ 17         self.name = name 18          19         #啟動或停止服務時等待操作成功等待時間 20         self.wait_time = 0.5 21         #啟動或停止服務時最大等待時間,超過時返回超時提示 22         self.delay_time = 10 23         self.scm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_access) 24  25  26         if self.is_exists(): 27             try: 28                 self.handle = win32service.OpenService(self.scm, self.name, win32service.SC_MANAGER_ALL_ACCESS) 29             except Exception, e: 30                 self.log(e) 31         else: 32             print '服務 %s 沒有安裝'.encode('gbk') % self.name 33              34  35     def is_stop(self): 36         """檢查服務是否停止""" 37         flag = False 38         try: 39             if self.handle: 40                 ret = win32service.QueryServiceStatus(self.handle) 41                 flag = ret[1] != win32service.SERVICE_RUNNING 42         except Exception, e: 43             self.log(e) 44         return flag 45  46     def start(self): 47         """開啟服務""" 48         try: 49             if self.handle: 50                 win32service.StartService(self.handle, None) 51         except Exception, e: 52             self.log(e) 53         status_info = win32service.QueryServiceStatus(self.handle) 54  55         if status_info[1] == win32service.SERVICE_RUNNING: 56             return '啟動服務%s成功'.encode('gbk') % self.name 57         elif status_info[1] == win32service.SERVICE_START_PENDING: 58             #如果服務正在啟動中則延遲返回啟動信息,直到啟動成功,或返回啟動時間過長信息 59             start_time = datetime.datetime.now() 60             while True: 61                 if (datetime.datetime.now() - start_time).seconds > self.delay_time: 62                     return '啟動服務%s時間太長'.encode('gbk') % self.name 63  64                 time.sleep(self.wait_time) 65                 if win32service.QueryServiceStatus(self.handle)[1] == win32service.SERVICE_RUNNING: 66                     return '啟動服務%s成功'.encode('gbk') % self.name 67         else: 68             return '啟動服務%s失敗'.encode('gbk') % self.name 69  70     def stop(self): 71         """停止服務""" 72         try: 73             status_info = win32service.ControlService(self.handle, win32service.SERVICE_CONTROL_STOP) 74         except Exception, e: 75             self.log(e) 76         if status_info[1] == win32service.SERVICE_STOPPED: 77             return '停止服務%s成功'.encode('gbk') % self.name 78         elif status_info[1] == win32service.SERVICE_STOP_PENDING: 79             start_time = datetime.datetime.now() 80             while True: 81                 if (datetime.datetime.now() - start_time).seconds > self.delay_time: 82                     return '停止服務%s時間太長'.encode('gbk') % self.name 83  84                 time.sleep(self.wait_time) 85                 if win32service.QueryServiceStatus(self.handle)[1] == win32service.SERVICE_STOPPED: 86                     return '停止服務%s成功'.encode('gbk') % self.name 87         else: 88             return '停止服務%s失敗'.encode('gbk') % self.name 89  90     def restart(self): 91         """重啟服務""" 92         if not self.is_stop(): 93             self.stop() 94         self.start() 95         return win32service.QueryServiceStatus(self.handle) 96  97     def status(self): 98         """獲取運行的狀態""" 99         try:100             status_info = win32service.QueryServiceStatus(self.handle)101             status = status_info[1]102             if status == win32service.SERVICE_STOPPED:103                 return "STOPPED"104             elif status == win32service.SERVICE_START_PENDING:105                 return "STARTING"106             elif status == win32service.SERVICE_STOP_PENDING:107                 return "STOPPING"108             elif status == win32service.SERVICE_RUNNING:109                 return "RUNNING"110         except Exception, e:111             self.log(e)112 113     def close(self):114         """釋放資源"""115         try:116             if self.scm:117                 win32service.CloseServiceHandle(self.handle)118                 win32service.CloseServiceHandle(self.scm)119         except Exception, e:120             self.log(e)121 122     def is_exists(self):123         """windows服務是否已安裝"""124         statuses = win32service.EnumServicesStatus(self.scm, win32service.SERVICE_WIN32, win32service.SERVICE_STATE_ALL)125         for (short_name, desc, status) in statuses:126             if short_name == self.name:127                 return True128         return False129 130     def log(self, exception):131         132         print(exception)133         134         135 136 if __name__=='__main__':137 138     app= ServiceManager('AAaservice')139     msg= app.is_exists()  # 判斷是否安裝  (以下操作必須先判斷服務是否存在)140     #msg= app.is_stop()  # 判斷服務是否停止141     #msg= app.status()  # 查看服務的狀態142     #msg= app.start()  # 開啟服務143     #msg= app.stop()  # 暫停服務   (服務開啟才能停止,else error)144     #msg= app.restart()  # 重啟服務145     146     print(msg)

 

 

7.參考地址:

python添加服務:         http://blog.csdn.net/kmust20093211/article/details/42169323
python添加服務:         http://www.chrisumbel.com/article/windows_services_in_python
打包無法運行服務:        http://zhangweide.cn/archive/2013/pyinstaller-package-windows-service.html
python管理window服務  https://github.com/zhulin3141/PPServ/edit/master/service_manager.py

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 虹口区| 迁安市| 平塘县| 呼图壁县| 济阳县| 安多县| 葵青区| 铜梁县| 鄄城县| 宁晋县| 万宁市| 新田县| 乌兰县| 丰宁| 宜兰县| 华坪县| 邵阳市| 恩平市| 通化市| 合肥市| 藁城市| 射洪县| 乐都县| 柘城县| 许昌市| 桦南县| 富蕴县| 马鞍山市| 东莞市| 大冶市| 古交市| 泌阳县| 依安县| 叶城县| 海原县| 米林县| 昌乐县| 乌兰浩特市| 白沙| 宁河县| 赤壁市|