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 mysqldb连接数据库
Mar 16 Python
在 Django/Flask 开发服务器上使用 HTTPS
Jul 03 Python
使用Python制作获取网站目录的图形化程序
May 04 Python
Python实现视频下载功能
Mar 14 Python
Python列表list操作符实例分析【标准类型操作符、切片、连接字符、列表解析、重复操作等】
Jul 24 Python
Python Tkinter实现简易计算器功能
Jan 30 Python
Python实现的拟合二元一次函数功能示例【基于scipy模块】
May 15 Python
Python和Java的语法对比分析语法简洁上python的确完美胜出
May 10 Python
python实现在一个画布上画多个子图
Jan 19 Python
Python多线程的退出控制实现
Aug 10 Python
Python爬虫之Selenium实现键盘事件
Dec 04 Python
详解python中的三种命令行模块(sys.argv,argparse,click)
Dec 15 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
让CodeIgniter的ellipsize()支持中文截断的方法
2014/06/12 PHP
Opcache导致php-fpm崩溃nginx返回502
2015/03/02 PHP
PHP正则+Snoopy抓取框架实现的抓取淘宝店信誉功能实例
2017/05/17 PHP
ThinkPHP框架获取最后一次执行SQL语句及变量调试简单操作示例
2018/06/13 PHP
js利用Array.splice实现Array的insert/remove
2009/01/13 Javascript
JavaScript 嵌套函数指向this对象错误的解决方法
2010/03/15 Javascript
jquery表单验证框架提供的身份证验证方法(示例代码)
2013/12/27 Javascript
JS保留两位小数,多位小数的示例代码
2014/01/07 Javascript
node.js中的fs.rmdir方法使用说明
2014/12/16 Javascript
基于jQuery+Cookie实现的防止刷新的在线考试倒计时
2015/06/19 Javascript
JS实现的自定义右键菜单实例二则
2015/09/01 Javascript
seajs加载jquery时提示$ is not a function该怎么解决
2015/10/23 Javascript
学习Angular中作用域需要注意的坑
2016/08/17 Javascript
浅谈javascript中的事件冒泡和事件捕获
2016/12/28 Javascript
浅谈JS中的常用选择器及属性、方法的调用
2017/07/28 Javascript
原生JavaScript实现Ajax异步请求
2017/11/19 Javascript
node中的cookie的具体使用
2018/09/13 Javascript
iview通过Dropdown(下拉菜单)实现的右键菜单
2018/10/26 Javascript
使用webpack构建应用的方法步骤
2019/03/04 Javascript
jQuery实现消息弹出框效果
2019/12/10 jQuery
Vue组件通信入门之Provide和Inject机制
2019/12/29 Javascript
使用PM2+nginx部署python项目的方法示例
2018/11/07 Python
对python xlrd读取datetime类型数据的方法详解
2018/12/26 Python
Pycharm新手教程(只需要看这篇就够了)
2019/06/18 Python
python 调试冷知识(小结)
2019/11/11 Python
python 基于PYMYSQL使用MYSQL数据库
2020/12/24 Python
汇集了世界上最好的天然和有机美容产品:LoveLula
2018/02/05 全球购物
小学生自我鉴定
2013/10/12 职场文书
《海伦?凯勒》教学反思
2014/04/17 职场文书
安全技术说明书
2014/05/09 职场文书
优秀管理者事迹材料
2014/05/22 职场文书
家长会标语
2014/06/24 职场文书
自愿离婚协议书范本
2014/09/13 职场文书
创业计划书之物流运送
2019/09/17 职场文书
nginx限制并发连接请求数的方法
2021/04/01 Servers
php png失真的原因及解决办法
2021/10/24 PHP