使用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(
\”iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAACQdJ\”
\”REFUWIXFl31s1eUVxz/P7+2+997evve2pZbaQmmhCOIL9QVBgsjEGSMZOHRGjTFmWcymy7Ko\”
\”WcKy+YeJy7Kha4zMbWEO4xadSp0EQQiiFUeLopTSN9rblkLbe+/v3vt7e/YHLwFh1IQsO8kv\”
\”v3++ec73Oed8zzmPkFIK/o+mzAQQQigNDQuWxGKxWiHEjPhQSJRXFfjqvy0BbSZAbW1j/f33\”
\”/+ztUCie6+z8cG9NTUv74GD3LimldT4uJkTstpbCR7esu/rhZCaXjgixMiXliSsmkEg0rZjf\”
\”sqI4GIpTV3fLfYsXrV+za/fWXfF42VMnT452AyRCRuuzd8zevH5R8TWlhYp2PGV5H7Sk7wba\”
\”r5hATc2ClYoaJ2sKXMegtGxucM2dz65KVC5e0ti44vGa3Gfpl+6c9+rqpqJiRXfB8kj4NWVF\”
\”XdGjxUJsPSFl+ooIRMKJ5qwp8CS4jsSywLY9Zs9eFheO03732LPW8lklceEIQIDrIYTkhorC\”
\”+fWJSBOw/4oICBGuNE2JlOC6Ett2yOctbDvPunmj4TbPQGSzgB9cBdTTdXp1uMCYFQ61zUTg\”
\”klUthCj1BbW7am8o+ZEwdMM0bUzTwjRzZLM5crkchaEUi2omEJkMmGlIp8HMgelA1iHsuCQC\”
\”SsNMFzwXgXg8XlC9oHJF0201jz29ff3NicUBw9Xz6HvDmP/OnImAi+M4OI5Dc6tJIG1DJg2O\”
\”A5aF1HWEqiEVBXSNYJF6/YP3iyfyrsLoqHHi1CnRMzam9Q4PpyallN45Ao2ts2984BfrX2hd\”
\”1XBNrE7VTHGCrJwgk7cpazjF9HFJf5+J53m4rosis1SZ78BXe07f3D5NAF1HNsyFW+6A+jRP\”
\”66/OJ8BvpGGQMSsZGSmxjhwJDXzyaW7H/Pllvz14cLRbA/CFQwULb21prZgd00zGAZBIAMyC\”
\”w7TdtJax0RTj41k8zyPEBKGh3bjHvkZJpxG2BZEg3LcC1m4E0Q9TvydsDCBCAvyCgqhGeUWB\”
\”0bqwtv6mmyP1PUemvwa6FYCuPV27Ptr+0b6cM41DHldaeNLB8zzG5RFy0V6WXFeE61nkciae\”
\”lUGdEuROSTJZF9vOIR+OI9eVIM3XYOgpsPoRngQPkC6QB0xgioH+Y5OHDg3uOFeEUkrz3fZ/\”
\”PfNFZ/d0Xk5jk8FxLVzXxbQz7E7/BX9E0NxcAeTIuy65EwrmlMdEDvJrJKwewerbhte3Faw0\”
\”wgNcwAFcG+QUgglcd5gdOw7t7emZ6r5ABUOHkx9t+3XHC2Mjw17ezWDZFpZl4Tg2A85+PrG3\”
\”EIxEKC+vJItCctQif3KadAh8yyH9RZrcQBLXOc+xAzgSLMBLIeUox3r7ctu3D7dLKZ0LVCCl\”
\”9IQQvwqWi9oVTzZt9BWpimVZ2LaNZec4bLxGf3CYSGADmq+Ifd4cbpruIN8CUxkYnAqRLi1D\”
\”L6mm0EhQiEbMO4phf45QMiA8PHWSP/0xtWPXLue9i2R4hoTVGA+01ziBexp++lBBpqyICX2Y\”
\”UXWAEaWfZMUHHDc+xlewiC4ZpUmLUjFh88aHCoe/W0+kpJTy+CwS2gJm6dfgUUzIGUA1nyeQ\”
\”fY8/v+mNbX7Z+aGUMneu55y/D4SFKH1xef2+H1xVWIsQWEtXkWtbyWiZxrBxjBHvc0bHviL1\”
\”WT+xLb08GCojsmQOf+3o4pkNxRRFkhQF/cQDAaKBMMXhckrCVRT442S/3O09//jHTxw5kNp8\”
\”QdM7S0AIoTy6sHLzb5Y3PexzXMhmIJPBs2yscAjT7zGdmyQ1eIr80QxhRcVf6idUFWNTdiUd\”
\”yx+hsuofFJa8RSygEwoE8Pv9BINBfD4fhuHjy3dGxt58unPVeN/k5xeloD4anP/QtZX3+gKA\”
\”o4MMguuh2Db+5Ai+1DThlMnJLFBTQXFFkNHFfSjNaSb3BrCH8tTVPkGJv5op7TU0TcMwDHRd\”
\”x+fz4fcFuP7ellJnwtceCoXWZDKZ5AUqWD4nsrE54Y+hu6BJ8OlgGKAboOug6aiaQrS1itKl\”
\”jbhLPQLNLtFrBY0tJxkatxhJmtxY9gD1keWOpmlomoau6+i6jqEG8Ysoy9YtbW373sIfn/Wr\”
\”nM397U0Fq4MhCZoLqnd6qmk6aCqoGqIggvKdpfhvm4WYO4SysJ9ACIR/EcHYLHL+GP/sStHd\”
\”b7Gs+EEnqEcsRVFQVRVN1dFFAEOEiccrlFUbb99YPae6+VwKEuVaja5TnnMd/IqKUDxQJCgC\”
\”hAKlcVh9D+KqEGQ2Q+gomidRbUC/g4w3D4JBpKrywoenaCgv14pDcycnlcPFiqKgCBUFDVXq\”
\”aMJPXWNDcf28uruA07Pg66RzcNO7g2veTUzftbAicnMiGKot1vxhw7KVuqtNf7QtCo07Qe+C\”
\”aBIcEA5gBHBFG1+dKoVAEDSVMU/huZ1Z7fvL5qRl5Iu4lFKRSKSUmKkch/YcONH9Qc/rfUcG\”
\”tl0kwzNqCM4pDhYENCWWMu2qP2yx37v1VqkgON3XPQkOSBuQtUzEd3LDKzo90xqoGqgKQgia\”
\”1TfS19VvCQYCPiU37lqTffZnQwcm/z50ILltsGe874Jx/I1mZHJ6aiSFEAPTHh6hM+u4BFwB\”
\”NqBKUErZ+mWeHjMCAQM0DVQVhKBrZ0rr+smeNbjuYSB5fvM53y6750spzeOjvl60QtCKQI+C\”
\”zwA/CL+gN1fOpo+j4PMjAn4CQR/xoEZxUCMgbAtXOyyl7Ptvzi8ZgW9aV5e/I29VN/h8GmAh\”
\”mULoJxlJZryH2hvMZCwUVgIGUb9K3BBENNAUGMiOJbPkT850/owvnc5O9/VDh6KWpAZJAijj\”
\”aG/Ue26T8ru9L/1tJfte6QliUeITVPihOihJaFm0ycF9wGVX8m9FYP/+9Kfvv+/scN1qTLOU\”
\”t97yhh95JP1YZ2frk/Zo375oxzNL3C0P/FJ2vT0cyY95lX5JdKrXccd6tp0ttMvZRSq4lK1a\”
\”NXf1hg3znz94MHkwna57de3adX2qqiqu6yoAlmXR0bGjqmss1xasbrneS08qHS///F4p5eRM\”
\”ZyOlFFJK9cz/kh+gAkUvvvii73I4KaWor6/3hcPhkplwZ31+qwj8L+0/pB1WIoQcFx8AAAAA\”
\”SUVORK5CYII=\”)
config.xml
复制代码 代码如下: