用python检测窗体状态

之前的文章说了在做客户端的爬虫的时候我们需要对爬取的应用程序进行进程的监控,对出现的异常进行处理。后面又发现,其实在Windows上,窗体和进程的似乎没有什么关系(不知道对不对,比较对Windows的图形化不是很熟悉,错了请指正),就是进程一直都是很正常的,但是窗体可能出现未响应的情况。这个问题我想大家其实都遇过,电脑卡的时候,点击一个窗口,然后窗口卡了一下,再点击的时候整个窗口就变白了,然后在左上角跳出一个窗体未响应的提醒。就是这个样子的。
image

这个其实涉及的知识点蛮多的,首先是win32方面的只是,然后还有mfc方面的知识,最后其实才是python方面的处理。我在网上找到了一个相应的文章判断窗体是否无响应,但是可能是我的水平不够高吧,对于一些解决方法看得云里雾里的。在着手解决的时候,自己old school的思维风格又占据了上风,强行要使用Windows系统进行窗体状态的监测,毕竟mfc这东西就是你Windows提出来的,不依靠你自身解决依靠谁。

在Windows方面,python给出的资料确实有点少得可怜,我也是到处收集到一点代码片段,再慢慢组合起来,慢慢的摸索的,连猜带蒙写出来的,其实我给出的代码我自己本身也还是有挺多的不清错的地方,就希望有这方面的大神可以给点参考。

还是写成了模块,对于工作上的信息进行了隐匿。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# coding:utf-8
import win32com.client
import win32api
import win32gui
import win32process
import win32pdh
import ctypes
import time
"""
该模块为了解决客户端在爬取数据的时候的窗体未响应问题
"""
class Listen_gui_status():
@staticmethod
def check_gui():
# junk是CPU的一些运行字段,instances是所有的进程名称,类型为list
junk, instances = win32pdh.EnumObjectItems(None, None,'process', win32pdh.PERF_DETAIL_WIZARD)
# print(instances)
proc_ids=[]
proc_dict={}
ubank_proc=None
for instance in instances:
if instance in proc_dict:
proc_dict[instance] = proc_dict[instance] + 1
else:
proc_dict[instance]=0
# print(proc_dict)
# print(proc_dict.items())
for instance, max_instances in proc_dict.items(): # 此段方法是统计同名进程有多少个
for inum in range(max_instances+1):
# PdhOpenQuery:获取性能监视器数据查询句柄,返回一个句柄
hq = win32pdh.OpenQuery()
'''
MakeCounterPath:使用PDH_COUNTER_PATH_ELEMENTS结构中指定的成员创建一个完整的计数器路径。
如果函数成功,则返回ERROR_SUCCESS。
如果函数失败,返回值是系统错误代码或PDH错误代码
'''
path = win32pdh.MakeCounterPath( (None,'process',instance, None, inum,'ID Process') )
print('inum',inum,'hq',hq,'path',path)
# PdhAddCounter:添加计数器
counter_handle=win32pdh.AddCounter(hq, path)
# CollectQueryData:收集指定查询中所有计数器的当前原始数据值,并更新每个计数器的状态码。
win32pdh.CollectQueryData(hq)
# GetFormattedCounterValue:获取指定计数器数值
types, val = win32pdh.GetFormattedCounterValue(counter_handle, win32pdh.PDH_FMT_LONG)
proc_ids.append((instance,str(val)))
win32pdh.CloseQuery(hq)
proc_ids.sort()
for proc_name in proc_ids:
if proc_name[0]==u'QQ.exe':
ubank_proc=proc_name[1]
# print(proc_name[1])
hWndList = []
qq_hWnd=[]
# 获取窗口句柄
win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hWndList)
# print ('------------------------------')
# print (hWndList)
# print ('------------------------------')
# 迭代
for hWnd in hWndList:
# 获取窗口句柄对应的线程ID和进程ID
threadId, process_id = win32process.GetWindowThreadProcessId(hWnd)
if process_id==int(ubank_proc):
# print(threadId, process_id,hWnd)
ubank_hWnd.append(hWnd)
for hWnd in qq_hWnd:
'''
关于IsHungAppWindow(),Microsoft官方给出的解释是:
The return value is TRUE if the window stops responding; otherwise, it is FALSE. Ghost windows always return TRUE.
具体可以查看https://msdn.microsoft.com/en-us/library/windows/desktop/ms633526(v=vs.85).aspx
'''
status = ctypes.windll.user32.IsHungAppWindow(hWnd)
if status:
time.sleep(30)
else:
pass
if __name__=='__main__':
Listen_gui_status.check_gui()

本文地址:http://damiantuan.xyz/2018/04/05/用python检测窗体状态/
转载请注明出处,谢谢!

坚持原创技术分享,您的支持将鼓励我继续创作!
-------------本文结束感谢您的阅读-------------