求助, Python 监控 windows 程序,崩溃后自启动

2020-11-19 16:27:55 +08:00
 jackpot
最近要写一个监控程序,监控 windows 服务器的程序,因为总崩溃;
网上的文章总是通过监控进程存在与否来判断是否重启;
但是这边.net 写的通讯程序崩溃后进程还是在的,无法通过进程有无来判断是否重启;
(崩溃后会弹出 windows 问题报告的窗口,显示“xxx 已停止工作”)
应该如何来判断程序是否崩溃呢?
2829 次点击
所在节点    Python
17 条回复
lewis89
2020-11-19 16:34:39 +08:00
findWindow 然后把窗口标题名字拿出来 看看 如果匹配上就直接 kill 掉

v2 应该会 windows 这种开发的人 很少了,我会用 findWindow 也是上初中写过 win32
lewis89
2020-11-19 16:35:32 +08:00
用 spy++先看下窗口的 lpcalss 什么的
lllllliu
2020-11-19 16:37:39 +08:00
是否。。可以试试 socket 来回发包检查。。
hxy100
2020-11-19 16:39:08 +08:00
这种工作交给 AutoHotKey 或者 AutoIt3 来完成最好,用 Python 太鸡肋
h82258652
2020-11-19 16:46:40 +08:00
把那个程序改成 Windows 服务吧,GUI 程序不靠谱的
ysc3839
2020-11-19 16:49:34 +08:00
正确解法是不要让那个“xxx 已停止工作”显示,父进程先用 SetErrorMode 关闭这个提示,再启动子进程,子进程崩溃了也不会出现这个提示了。
CallMeReznov
2020-11-19 16:52:24 +08:00
把你那个程序添加到数据执行保护的排除列表里,然后直接判断进程是否存在即可.
写个批处理都行
CallMeReznov
2020-11-19 16:55:31 +08:00
或者本身服务都是你自己写的,你自己禁用这个崩溃提示不可以吗?
CSDN 都有解决方案.
jackpot
2020-11-19 17:03:18 +08:00
@CallMeReznov
数据执行保护的排除列表试过了,不行,崩溃了进程还是在。
服务是前人留下的,现在都没人改了
vopsoft
2020-11-19 17:11:51 +08:00
这个不好弄
我以前是监控程序数据 如果数据长时间无变化就告警
krixaar
2020-11-19 17:12:05 +08:00
组策略>计算机配置>管理模板>Windows 组件>Windows 错误报告>阻止显示严重错误的用户界面
wysnylc
2020-11-19 17:12:11 +08:00
process lasso 有这个功能
mingl0280
2020-11-19 19:38:48 +08:00
jackpot
2020-11-20 09:18:30 +08:00
感谢大家,问题解决了,确实可以通过修改注册表来禁止弹出 werfault 窗口,这样程序出现 crash 后进程直接就没了,就可以判断进程有无来自动重启了
jackpot
2020-11-20 09:28:23 +08:00
禁用 werfalut.exe ,系统 windows server 2012 R2,将 DontShowUI 从 0 改为 1 就行了,Disabled 不用改,改了事件查看器里就没程序 crash 的记录了
[HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting]
"Disabled"=dword:00000001
"DontShowUI"=dword:00000001
jones2000
2020-11-20 12:03:44 +08:00
Findwindow 监控弹出窗口, 弹出了, 直接杀进程,然后再启动。
keepwalk2020
2020-11-20 20:28:06 +08:00
在策略组设置好之后.每隔开一段时间给所有运行的 pid 做一次 snapshot,然后把 pid 映射成 exe 程序名称,如果发现目标程序不在了,就启动目标程序,如果发现目标程序还在,就什么都不做,具体代码实现如下:这个程序是守护 VNC,记得换成你需要守护的程序名称,运行环境 python 2.7

# -*- coding: utf-8 -*-
#!/usr/bin/python

import os, sys, gc, time, ctypes, subprocess
from ctypes import byref, sizeof, windll, c_size_t, c_char, c_void_p, Structure, WinError#, POINTER
from ctypes.wintypes import DWORD, LONG

class PROCESSENTRY32(Structure):
_fields_ = [
('dwSize', DWORD),
('cntUsage', DWORD),
('th32ProcessID', DWORD),
('th32DefaultHeapID', c_size_t),
('th32ModuleID', DWORD),
('cntThreads', DWORD),
('th32ParentProcessID', DWORD),
('pcPriClassBase', LONG),
('dwFlags', DWORD),
('szExeFile', c_char * 260),
] #LPPROCESSENTRY32 = POINTER(PROCESSENTRY32)

def syspid_snapshot(dwFlags=2, th32ProcessID=0):
hSnapshot = ctypes.windll.kernel32.CreateToolhelp32Snapshot(dwFlags,th32ProcessID)
INVALID_HANDLE_VALUE = ctypes.wintypes.c_void_p(-1).value
if hSnapshot == INVALID_HANDLE_VALUE: raise ctypes.WinError()
return hSnapshot

def get_all_explr_pids():
all_pid=[]
pse = PROCESSENTRY32()
pse.dwSize = ctypes.sizeof(PROCESSENTRY32)
hSnapshot = syspid_snapshot()
pse_crt = ctypes.windll.kernel32.Process32First(hSnapshot, ctypes.byref(pse))
while pse_crt:
try :
hProcess = ctypes.windll.kernel32.OpenProcess(0x0410, 0, pse.th32ProcessID)
if hProcess:
buf = (ctypes.c_wchar * 1024)()
ctypes.windll.psapi.GetModuleFileNameExW(hProcess, 0, ctypes.pointer(buf), 1024+1)
buf = buf[:].encode('utf-8')
buf = buf[:buf.index("\0")]
if str(buf).split('\\')[-1].lower() == 'vncserver.exe': all_pid.append( str(pse.th32ProcessID) )
except : return (-1,)
pse_crt = ctypes.windll.kernel32.Process32Next(hSnapshot, ctypes.byref(pse))
ctypes.windll.Kernel32.CloseHandle(hProcess)
ctypes.windll.Kernel32.CloseHandle(hSnapshot)
return tuple(all_pid)

def protect_VNC():
sys.stdout.write('Daemon started with pid %d\n' % os.getpid())
sys.stdout.write('Daemon stdout output\n')
sys.stderr.write('Daemon stderr output\n')
vnc_exe_path = r"C:\\Program Files\\RealVNC\\VNC Server\\vncserver.exe"
c = 0
while True:
sys.stdout.write('%d: %s\n' %(c, time.ctime()))
sys.stdout.flush()
c = c+1
time.sleep(60*20) #check vnc pid each 20 minutes
#time.sleep(12) #check vnc pid each 20 minutes
try:
vnc_flg = get_all_explr_pids()
print(vnc_flg)
except :
continue
if len(vnc_flg) > 0:
if vnc_flg[0] != -1:
print('vnc is running\n\n')
else :
print('can not find vnc pid \n\n')
try:
subprocess.Popen(vnc_exe_path)
except:
pass
else :
print('can not find vnc pid \n\n')
try :
subprocess.Popen(vnc_exe_path, shell=True)
#ppp = os.popen( vnc_exe_path ).read()
except :
pass

if __name__ == '__main__':
protect_VNC()

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/727190

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX