目的:
针对Windows下进程异常退出后,此程序自动启动被监控进程。如:监控Serv-U.exe

程序是使用python语言编写,可在Windows下双击MonitorWin32Process.exe直接运行。程序会按照config.ini配置文件,进行监控进程。如果没有被监控的进程,则会按照进程启动路径自动启动。
详细使用请查看压包内的使用说明.

1.. 环境配置
2.. 使用说明
3.. 待改进
4.. 下载链接

5.. 发邮件通知功能源码.

1.. 环境配置

需要的安装包python、wmi

介绍wmi 网站

  1. http://tgolden.sc.sabren.com/python/wmi/index.html#what-is-it 

xp 安装WMI

  1. Windows installer: http://timgolden.me.uk/python/downloads/WMI-1.4.6.win32.exe 

win7 将安装包解压到python lib 目录下,详细查看readme文件。

  1. Zipped-up source: http://timgolden.me.uk/python/downloads/WMI-1.4.6.zip 
环境配置可能遇到的问题
  1. C:\Python27\Lib\WMI-1.4.6>python setup.py install 
  2. Traceback (most recent call last): 
  3.   File "setup.py", line 2, in <module> 
  4.     import wmi 
  5.   File "C:\Python27\Lib\WMI-1.4.6\wmi.py", line 88, in <module> 
  6.     from win32com.client import GetObject, Dispatch 
  7.     ImportError: No module named win32com.client 
解决方法:
相应python版本的win32扩展,安装后问题即解决。网址如下:
http://sourceforge.net/projects/pywin32/files/

 

程序代码

  1. #!-*- encoding: utf-8 -*- 
  2. import logging 
  3. import wmi 
  4. import os 
  5. import time 
  6. from ConfigParser import ConfigParser 
  7.  
  8. CONFIGFILE='./config.ini' 
  9. config = ConfigParser() 
  10. config.read(CONFIGFILE) 
  11.  
  12. ProgramPath = config.get('MonitorProgramPath','ProgramPath') 
  13. ProcessName = config.get('MonitorProcessName','ProcessName') 
  14.  
  15.  
  16. c = wmi.WMI() 
  17.  
  18. def main(): 
  19.   
  20.    ProList = []             #如果在main()函数之外ProList 不会清空列表内容. 
  21.     for process in c.Win32_Process(): 
  22.         ProList.append(str(process.Name)) 
  23.  
  24.     if ProcessName in ProList: 
  25.         print "Service " + ProcessName + " is running...!!!" 
  26.         if os.path.isdir("c:\MonitorWin32Process"): 
  27.             pass 
  28.         else: 
  29.             os.makedirs("c:\MonitorWin32Process") 
  30.  
  31.     else: 
  32.         print "Service " + ProcessName + " error ...!!!" 
  33.         os.startfile(ProgramPath) 
  34.  
  35. if __name__ == "__main__": 
  36.     while True: 
  37.         main() 
  38.         time.sleep(300) 
 
1..2 将py程序编译成windows下可执行文件
py2exe下载地址,找到与安装的Python 版本相同的py2exe版本.
  1. http://sourceforge.net/projects/py2exe/files/py2exe/0.6.9/ 
  2.  
  3. from distutils.core import setup 
  4. import py2exe 
  5.  
  6. setup(console=['MonitorWin32Process.py'],   
 
问题描述:
当执行C:\Documents and Settings\Administrator\Desktop\temp>python setup.py py2exe
执行一段代码后出现 弹出一个窗口提示Python.exe 程序将要结束的

解决方法 :

这是因为setup.py中 logo.ico图片是由原来的gif 直接修改后缀名为ico 造成的.
  1. from distutils.core import setup 
  2. import py2exe 
  3.   
  4. setup( 
  5. console = [{"script" : "MonitorWin32Process.py", "icon_resources" : [(1, "logo.ico")]}] 

注: 将以上 console 修改windowns 在windowns下的可执行程序,将不会出现cmd窗口.


2.. 使用说明
2..1 必须先配置config.ini
配置压缩包中config.ini文件,修改服务启动的路径和进程在任务管理器中的名字.

  1. [MonitorProgramPath] 
  2. ProgramPath: C:\Program Files\RhinoSoft.com\Serv-U\Serv-U.exe 
  3.   
  4. [MonitorProcessName] 
  5. ProcessName: Serv-U.exe 
  6.   
  7. 如: 
  8. [MonitorProgramPath] 
  9. ProgramPath: C:\Program Files\Tencent\QQ\Bin\QQ.exe 
  10.   
  11. [MonitorProcessName] 
  12. ProcessName: QQ.exe 

2..2
将MonitorWin32Process.exe拖到启动中. 即可开机启动.

3.. 待改进
3..1 出现错误时在屏幕上一闪马上消失了.

应添加下面红色代码,这样有利于排查错误.
 
  1. if ProcessName in ProList: 
  2.     print "Service " + ProcessName + " is running...!!!" 
  3.     if os.path.isdir("c:\MonitorWin32Process"): 
  4.         pass 
  5.     else: 
  6.         os.makedirs("c:\MonitorWin32Process") 
  7.  
  8. else: 
  9.     print "Service " + ProcessName + " error ...!!!" 
  10.     os.startfile(ProgramPath) 
  11.     time.sleep(5) 

3..2 应该加上日志功能.

   按天或按月进行分日志.

4.. 下载链接

  1. http://down.51cto.com/data/381581 

5. 发邮件通知功能源码.

  1. #!-*- encoding: utf-8 -*- 
  2. import wmi,os,time,smtplib 
  3. from ConfigParser import ConfigParser 
  4. from email.mime.text import MIMEText 
  5.  
  6. #### 发送邮件 代码开始 
  7.  
  8. ##################### 
  9. #获取smtp服务器,用户名、口令、邮箱的后缀、收件人列表 
  10. CONFIGFILE="./config.ini" 
  11. config = ConfigParser() 
  12. config.read(CONFIGFILE) 
  13.  
  14. mailHost = config.get('mailHost','Host') 
  15. mailUser = config.get('mailUser','User') 
  16. mailPass = config.get('mailPass','Pass') 
  17. mailPostfix = config.get('mailPostfix','Postfix') 
  18. mailToList = config.get('mailToList','toList') 
  19.  
  20. #获取主题 
  21. subject = config.get('subject','subject') 
  22.  
  23.  
  24. ###################### 
  25.  
  26. def send_mail(mailToList,sub,content): 
  27.     ''' 
  28.     to_list:发给谁 
  29.     sub:主题 
  30.     content:内容 
  31.     ''' 
  32.     RealTime = time.strftime("%Y-%m-%d %X",time.localtime()) 
  33.     content = RealTime + " " + content 
  34.     me="Monitor"+"<"+mailUser+"@"+mailPostfix+">
  35.     msg = MIMEText(content,'plain','gb2312') 
  36.     msg['Subject'] = sub 
  37.     msg['From'] = me 
  38.     msg['To'] = mailToList 
  39.     try: 
  40.         s = smtplib.SMTP() 
  41.         s.connect(mailHost) 
  42.         s.login(mailUser,mailPass) 
  43.         s.sendmail(me, mailToList, msg.as_string()) 
  44.         s.close() 
  45.         return True 
  46.     except Exception, e: 
  47.         print str(e) 
  48.         return False 
  49. #### 发送邮件 代码结束 
  50.  
  51. dirName = "d:\MonitorWin32Process\\" 
  52. logSuffix = ".log" 
  53. logErrorSuffix = ".error.log" 
  54. config = ConfigParser() 
  55. config.read(CONFIGFILE) 
  56.  
  57. ProgramPath = config.get('MonitorProgramPath','ProgramPath') 
  58. ProcessName = config.get('MonitorProcessName','ProcessName')  
  59. SleepTime = config.get('ProcessSleepTime','SleepTime') 
  60.  
  61. if not os.path.isdir(dirName): 
  62.     os.makedirs(dirName) 
  63.  
  64. c = wmi.WMI() 
  65.  
  66. def main():  
  67.     ProList = []               #如果在main()函数之外ProList 不会清空列表内容. 
  68.     timetimeDay = time.strftime("%Y-%m-%d",time.localtime()) 
  69.     timetimeLog = time.strftime("%Y-%m-%d %X",time.localtime()) 
  70.     logFileName = dirName + timeDay + logSuffix 
  71.     logFileNameError = dirName + timeDay + logErrorSuffix 
  72.     if  not os.path.isfile(logFileName): 
  73.         file(logFileName,'a') 
  74.  
  75.     for process in c.Win32_Process():  
  76.         ProList.append(str(process.Name))  
  77.  
  78.     if ProcessName in ProList:  
  79.         content = timeLog + " Service " + ProcessName + " is running...!!!\n"  
  80.         logFile = open(logFileName,'a+') 
  81.         logFile.write(content) 
  82.         logFile.close() 
  83.  
  84.     else: 
  85.         content = timeLog + " Service " + ProcessName + " is error !!!" + "\n" 
  86.         logFile = open(logFileNameError,'a+') 
  87.         logFile.write(content) 
  88.         logFile.close() 
  89.         os.startfile(ProgramPath) 
  90.         send_mail(mailToList,subject,content) 
  91.          
  92.  
  93. if __name__ == "__main__": 
  94.     while True: 
  95.         main() 
  96.         time.sleep(int(SleepTime))