DDR爱好者之家 Design By 杰米

使用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>

DDR爱好者之家 Design By 杰米
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
DDR爱好者之家 Design By 杰米

稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!

昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。

这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。

而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?