python实现监控windows服务并自动启动服务示例


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 相关文章推荐
PYTHON正则表达式 re模块使用说明
May 19 Python
详解Python中用于计算指数的exp()方法
May 14 Python
python爬虫的工作原理
Mar 05 Python
如何运行带参数的python脚本
Nov 15 Python
python字符串下标与切片及使用方法
Feb 13 Python
pycharm激活码快速激活及使用步骤
Mar 12 Python
Python列表如何更新值
May 27 Python
Python-openCV开运算实例
Jul 05 Python
Python配置pip国内镜像源的实现
Aug 20 Python
python各种excel写入方式的速度对比
Nov 10 Python
Python爬虫之Selenium实现窗口截图
Dec 04 Python
Python基于Opencv识别两张相似图片
Apr 25 Python
解决python写的windows服务不能启动的问题
Apr 15 #Python
Python和php通信乱码问题解决方法
Apr 15 #Python
Python获取脚本所在目录的正确方法
Apr 15 #Python
使用Python获取CPU、内存和硬盘等windowns系统信息的2个例子
Apr 15 #Python
python中使用sys模板和logging模块获取行号和函数名的方法
Apr 15 #Python
python 动态获取当前运行的类名和函数名的方法
Apr 15 #Python
python使用百度翻译进行中翻英示例
Apr 14 #Python
You might like
模仿OSO的论坛(五)
2006/10/09 PHP
YII Framework框架教程之缓存用法详解
2016/03/14 PHP
jquery自动完成插件(autocomplete)应用之PHP版
2009/12/15 Javascript
JS中的this变量的使用介绍
2013/10/21 Javascript
一个JavaScript去除字符串末尾的空白实例代码
2014/09/22 Javascript
JS实现模拟百度搜索“2012世界末日”网页地震撕裂效果代码
2015/10/31 Javascript
JS中frameset框架弹出层实例代码
2016/04/01 Javascript
js添加千分位的实现代码(超简单)
2016/08/01 Javascript
简单分析javascript中的函数
2016/09/10 Javascript
js转换对象为xml
2017/02/17 Javascript
vue router动态路由下让每个子路由都是独立组件的解决方案
2018/04/24 Javascript
Vue实现自定义下拉菜单功能
2018/07/16 Javascript
jQuery中ajax请求后台返回json数据并渲染HTML的方法
2018/08/08 jQuery
vue+element项目中过滤输入框特殊字符小结
2019/08/07 Javascript
使用layer弹窗提交表单时判断表单是否输入为空的例子
2019/09/26 Javascript
Vue 打包的静态文件不能直接运行的原因及解决办法
2020/11/19 Vue.js
python:socket传输大文件示例
2017/01/18 Python
利用python实现命令行有道词典的方法示例
2017/01/31 Python
Python Flask前后端Ajax交互的方法示例
2018/07/31 Python
Django 日志配置按日期滚动的方法
2019/01/31 Python
解决pycharm运行程序出现卡住scanning files to index索引的问题
2019/06/27 Python
Visual Studio Code搭建django项目的方法步骤
2020/09/17 Python
日本一家专门经营各种箱包的大型网站:Traveler Store
2016/08/03 全球购物
Sandro Paris美国官网:典雅别致的法国时尚服饰品牌
2017/12/26 全球购物
营销与策划应届生求职信
2013/11/04 职场文书
会计实习自我鉴定
2013/12/04 职场文书
优秀员工自荐书范文
2013/12/08 职场文书
高二英语教学反思
2014/01/19 职场文书
护理中职生求职信范文
2014/02/24 职场文书
实习单位评语
2014/04/26 职场文书
学习焦裕禄同志为人民服务思想汇报
2014/09/10 职场文书
办公室文员工作自我鉴定
2014/09/19 职场文书
2014年个人思想工作总结
2014/11/27 职场文书
企业党支部工作总结2015
2015/05/21 职场文书
无罪辩护词范文
2015/05/21 职场文书
辩论赛主持人开场白
2015/05/29 职场文书