Posted in Python onApril 17, 2014
使用Python 2.7 + pywin32 + wxpython开发
每隔一段时间检测一下服务是否停止,如果停止尝试启动服务。进行服务停止日志记录
AppMain.py
#!/usr/bin/env python #-*- encoding:utf-8 -*- """ 1. 每隔一分钟检测一次服务状态 2. 如果发现服务状态已经停止,那么尝试启动服务 3. 自动记录日志 4. 任务栏图标显示 """ import sys; reload(sys); sys.setdefaultencoding('utf-8'); import win32service; import logging; from logging.handlers import RotatingFileHandler; import os.path; import wx; import AppResource; import webbrowser; from AppXml import *; C_APP_NAME = "Service Moniter 1.0"; C_LOG_DIR = os.path.altsep.join([os.path.curdir,'service.log']); C_CONFIG_PATH = os.path.altsep.join([os.path.curdir,'config.xml']); C_LOG_SIZE = 1048576; C_LOG_FILES = 3; C_APP_SITE = "http://www.du52.com/?app=service_moniter&version=1.0.0"; class ServiceControl(object): def __init__(self): self.scm = win32service.OpenSCManager(None,None,win32service.SC_MANAGER_ALL_ACCESS); # 检查服务是否停止 def isStop(self,name): flag = False; try: handle = win32service.OpenService(self.scm,name,win32service.SC_MANAGER_ALL_ACCESS); if handle: ret = win32service.QueryServiceStatus(handle); flag = ret[1]!=win32service.SERVICE_RUNNING; win32service.CloseServiceHandle(handle); except Exception,e: logging.error(e); return flag; # 开启服务 def start(self,name): try: handle = win32service.OpenService(self.scm,name,win32service.SC_MANAGER_ALL_ACCESS); if handle: win32service.StartService(handle,None); win32service.CloseServiceHandle(handle); except Exception,e: logging.error(e); # 退出 def close(self): try: if self.scm: win32service.CloseServiceHandle(self.scm); except Exception,e: logging.error(e); # 初始化日志 def InitLog(): logging.getLogger().setLevel(logging.ERROR); RtHandler = RotatingFileHandler(filename=C_LOG_DIR,maxBytes=C_LOG_SIZE,backupCount=C_LOG_FILES); RtHandler.setLevel(logging.ERROR); RtHandler.setFormatter(logging.Formatter('[%(asctime)s][%(levelname)s] %(message)s')); logging.getLogger().addHandler(RtHandler); logging.error('监控开始执行'); # 系统托盘图标 class TaskIcon(wx.TaskBarIcon): def __init__(self): wx.TaskBarIcon.__init__(self); self.SetIcon(AppResource.TaskIcon.getIcon(),C_APP_NAME); self.ID_NAME = wx.NewId(); self.ID_EXIT = wx.NewId(); self.ID_AUTHOR = wx.NewId(); self.Bind(wx.EVT_MENU,self.OnExitEvent,id=self.ID_EXIT); self.Bind(wx.EVT_MENU,self.OnHelpEvent,id=self.ID_AUTHOR); def OnHelpEvent(self,event): webbrowser.open_new(C_APP_SITE); def OnExitEvent(self,event): wx.Exit(); def CreatePopupMenu(self,event=None): menu = wx.Menu(); menu.Append(self.ID_NAME,C_APP_NAME); menu.AppendSeparator(); menu.Append(self.ID_AUTHOR,"技术支持"); menu.Append(self.ID_EXIT,"退出"); return menu; # 隐藏窗口 class Frame(wx.Frame): def __init__(self,timelen,services): wx.Frame.__init__(self,parent=None,title=C_APP_NAME); self.timelen = timelen*1000; self.services = services; self.Show(False); self.Bind(wx.EVT_TIMER,self.OnTimerEvent); self.Bind(wx.EVT_CLOSE,self.OnExitEvent); self.timer = wx.Timer(self); self.timer.Start(self.timelen); def OnTimerEvent(self,event): sc = ServiceControl(); for name in self.services: print name; if sc.isStop(name): logging.error('系统检测到服务[%s]停止'%(name,)); sc.start(name); sc.close(); def OnExitEvent(self,event): if self.timer: self.timer.Stop(); self.timer = None; # 进程 class Application(wx.App): def OnInit(self): # 初始化配置 xml = XmlNode(); if not xml.LoadFile(C_CONFIG_PATH): logging.error('配置文件不存在'); return False; timelen = xml.FindNode('time').GetInt(); if timelen<=0: logging.error('监控间隔时间必须大于0秒'); return False; services = xml.FindNode('services').GetChildrenList(tag='item'); if len(services)==0: logging.error('监控服务列表不能为空'); return False; self.taskbar = TaskIcon(); self.frame = Frame(timelen,services); return True; def OnExit(self): logging.error('监控停止执行'); self.frame.Close(); self.taskbar.RemoveIcon(); self.taskbar.Destroy(); if __name__ == '__main__': InitLog(); app = Application(); app.MainLoop();
AppXml.py
#!/usr/bin/env python #-*- encoding:utf-8 -*- """ XML操作封装 """ import os.path; import logging; import xml.etree.ElementTree as ElementTree; class XmlNodeValue(object): STRING = 1; INT = 2; FLOAT = 3; BOOL = 4; class XmlNodeMap(object): ATTR = 1; TEXT = 2; NODE = 3; class XmlNode(object): def __init__(self,currentNode=None,rootNode=None): self.currentNode = currentNode; self.rootNode = rootNode; # 加载XML文件 def LoadFile(self,path): if os.path.isabs(path): path = os.path.abspath(path); flag = False; try: self.rootNode = ElementTree.parse(path); if self.rootNode is not None: flag = True; self.currentNode = self.rootNode; except Exception,e: logging.error("XML文件加载失败"); logging.error(e.__str__()); return flag; # 加载XML内容 def LoadString(self,data): if data is None or len(data.strip())==0: return False; flag = False; try: self.rootNode = ElementTree.fromstring(data); if self.rootNode is not None: flag = True; self.currentNode = self.rootNode; except Exception,e: logging.error("XML内容加载失败"); logging.error(e.__str__()); return flag; # 检查数据是否载入正确 def IsLoad(self): return self.currentNode is not None and self.rootNode is not None; # 返回根节点对象 def GetRoot(self): return XmlNode(self.rootNode,self.rootNode); # 查找节点,开始为“/”从根节点开始查找,否则从当前节点查找 def FindNode(self,path): if path is None or len(path.strip())==0: return XmlNode(None,self.rootNode); path = path.strip(); node = None; if path[0]=='/': node = self.rootNode.find(path[1:]); else: node = self.currentNode.find(path); return XmlNode(node,self.rootNode); # 查找多节点 def FindNodes(self,path): if path is None or len(path.strip())==0: return XmlNode(None,self.rootNode); if path[0]=='/': nodes = self.rootNode.findall(path[1:]); else: nodes = self.currentNode.findall(path); return [XmlNode(node,self.rootNode) for node in nodes]; # 获取子节点列表 def GetChildrens(self,tag=None): return [XmlNode(node,self.rootNode) for node in self.currentNode.iter(tag=tag)]; # 格式化数据 def GetFormatData(self,node,type): if type==XmlNodeValue.STRING: v = node.GetStr(); elif type==XmlNodeValue.INT: v = node.GetInt(); elif type==XmlNodeValue.FLOAT: v = node.GetFloat(); elif type==XmlNodeValue.BOOL: v = node.GetBool(); else: v = node.GetData(); return v; # 获取子节点内容列表 # valueFormat 值类型 1 字符串,2 整数,3 小数,4 布尔值 def GetChildrenList(self,tag=None,valueFormat=XmlNodeValue.STRING): data = []; for node in self.GetChildrens(tag=tag): data.append(self.GetFormatData(node,valueFormat)); return data; # 获取子节点Map表 # keyType 1 使用属性值 2 使用子节点 # keyName 属性值名称或子节点名称 # valueType 1 使用属性值 2 使用子节点 # ValueName 属性值名称或子节点名称 def GetChildrenMap(self,tag=None,keyType=XmlNodeMap.ATTR,keyName="name",valueType=XmlNodeMap.TEXT,valueName=None,valueFormat=XmlNodeValue.STRING): data = {}; for node in self.GetChildrens(tag=tag): k,v = None,None; if keyType==XmlNodeMap.ATTR: if keyName is None or len(keyName.strip())==0: continue; k = node.GetAttrs().GetStr(keyName); elif keyType==XmlNodeMap.NODE: if keyName is None or len(keyName.strip())==0: continue; t = node.FindNode(keyName); if not t.IsLoad(): continue; k = t.GetStr(); elif keyType==XmlNodeMap.TEXT: k = node.GetStr(); else: continue; if k is None or len(k.strip())==0: continue; if valueType==XmlNodeMap.ATTR: if valueName is None or len(valueName.strip())==0: continue; v = self.GetFormatData(node.GetAttrs(),valueFormat); elif valueType==XmlNodeMap.NODE: if valueName is None or len(valueName.strip())==0: continue; t = node.FindNode(valueName); if t.IsLoad(): v = self.GetFormatData(t,valueFormat); elif valueType==XmlNodeMap.TEXT: v = self.GetFormatData(node,valueFormat); else: v = None; data[k] = v; return data; # 获取节点名称 def GetTag(self): if self.currentNode is None: return ""; return self.currentNode.tag; # 获取节点内容 def GetData(self,default=None): if self.currentNode is None: return default; return self.currentNode.text; def GetStr(self,default="",strip=True): data = self.GetData(); if data is None: return default; try: data = str(data.encode("utf-8")); if data is None: data = default; else: if strip: data = data.strip(); except Exception,e: print e; data = default; return data; def GetInt(self,default=0): data = self.GetData(); if data is None: return default; try: data = int(data); if data is None: data = default; except Exception: data = default; return data; def GetFloat(self,default=0.0): data = self.GetData(); if data is None: return default; try: data = float(data); if data is None: data = default; except Exception: data = default; return data; def GetBool(self,default=False): data = self.GetData(); if data is None: return default; data = False; if self.GetStr().lower()=="true" or self.GetInt()==1: data = True; return data; # 获取节点属性 def GetAttrs(self,default={}): return XmlAttr(self); class XmlAttr(object): def __init__(self,node): self.node = node; self.InitAttrs(); # 获取Node def GetNode(self): return self.node; # 设置Node def SetNode(self,node): self.node = node; self.InitAttrs(); # 初始化Node属性列表 def InitAttrs(self): if self.node is None or self.node.currentNode is None: self.attrs = {}; self.attrs = self.node.currentNode.attrib; # 获取属性 def GetAttrs(self): if self.attrs is None: self.InitAttrs(); return self.attrs; # 获取指定属性 def GetData(self,key,default=None): data = self.attrs.get(key); if data is None : data = default; return data; def GetStr(self,key,default="",strip=True): data = self.GetData(key); if data is None: return default; try: data = str(data.encode("utf-8")); if data is None: data = default; else: if strip: data = data.strip(); except Exception: data = default; return data; def GetInt(self,key,default=0): data = self.GetData(key); if data is None: return default; try: data = int(data); if data is None: data = default; except Exception: data = default; return data; def GetFloat(self,key,default=0.0): data = self.GetData(key); if data is None: return default; try: data = float(data); if data is None: data = default; except Exception: data = default; return data; def GetBool(self,key,default=False): data = self.GetData(key); if data is None: return default; data = False; if self.GetStr(key).lower()=="true" or self.GetInt(key)==1: data = True; return data; # 测试 if __name__ == "__main__": node = XmlNode(); print node.LoadFile(r"config.xml"); print node.FindNode("engine/headers").GetChildrenMap("header",XmlNodeMap.ATTR,"name",XmlNodeMap.TEXT,None,XmlNodeValue.STRING);
AppResource.py
#---------------------------------------------------------------------- # This file was generated by C:\Python27\Scripts\img2py # from wx.lib.embeddedimage import PyEmbeddedImage TaskIcon = PyEmbeddedImage( "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" "SUVORK5CYII=")
config.xml
<?xml version="1.0" encoding="utf-8" ?> <config> <!-- 需要监控的服务名称列表 --> <services> <item>Dhcp</item> </services> <!-- 间隔时间(单位秒) --> <time>10</time> </config>
python实现监控windows服务并自动启动服务示例
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@