Python自动化(1)——获取窗口句柄
前言
在现代生活中,人们的工作往往有很大的重复性。可能一个工作,会有90%的相似性,这时候,就会思考能否通过程序来代替人工。
Python作为近几年来大火的编程语言,其便捷性和高效性,使得我首选这个语言来实现自动化。其中,有很多公用的库,能大大提高开发的效率
(题外话:选择python语言,是因为这顺便也能让我学习一下python,说明一下,在写本自动化框架之前,我只用python写过一个公司下班和吃饭提醒机器人[基于企微机器人],因此本文难度不会很大,是初级篇[但是至少得入门,知道python的语法,会安装python库什么的])
Python版本:3.9.10
用到的库:time,pywin32(需安装),pyautogui(需安装),pyperclip(需安装)
获取窗口句柄的方式
获取窗口句柄一般有两种方法,第一种是直接通过窗口的标题获取;第二种是通过判断当前鼠标悬停的位置,来获取鼠标悬停位置下的窗口句柄。
通过窗口标题获取窗口句柄
def bindHwnd_1(self, windowName):
self._hwnd = win32gui.FindWindow(None, windowName)
print(‘hwnd:’+str(self._hwnd))
self._thread_id, self._process_id = win32process.GetWindowThreadProcessId(self._hwnd)
self._threadName = psutil.Process(self._process_id).name()
print("self._thread_id: "+str(self._thread_id))
print("self._threadName: "+str(self._threadName))
return self._hwnd
例子:新建一个文本文档并打开,通过窗口标题获取窗口句柄。首先需要获取窗口标题,打开任务管理器,找到记事本,打开记事本的子标题,里面“新建文本文档.txt – 记事本”就是窗口标题
测试代码以及结果:
使用这种方法,需要获取窗口标题,有时候不知道窗口标题,或者不想打开任务管理器找,可以通过代码遍历全部的窗口句柄,找到对应的窗口标题。
通过上面的方法,可以获取全部的窗口标题,但是此时就会出现第二个问题,那就是如果出现多个窗口标题相同的情况那该怎么办。
如果通过上述的办法获取窗口句柄,会随机获取到多个相同窗口标题的其中一个窗口的句柄。也可以使用第二种方法,通过鼠标悬停获取窗口句柄。
通过鼠标悬停获取窗口句柄
def bindHwnd_2():
point = win32api.GetCursorPos()
_hwnd = win32gui.WindowFromPoint(point)
print('hwnd:'+str(_hwnd))
_thread_id, _process_id = win32process.GetWindowThreadProcessId(_hwnd)
_threadName = psutil.Process(_process_id).name()
print("_thread_id: "+str(_thread_id))
print("_threadName: "+str(_threadName))
return _hwnd
keyboard.add_hotkey('ctrl+b',bindHwnd_2,suppress = False)
keyboard.wait()
上述代码中,使用了keyboard库中的wait方法来使程序维持在运行状态,并添加了ctrl+b快捷键运行绑定窗口句柄的方法。运行后,将鼠标移动到文本文档的空白位置,并按下键盘ctrl+b快捷键。
运行结果:
此时得到了窗口句柄,但是对比上下两种方法,发现窗口句柄是不一样的,其实通过第一种方法获取的窗口句柄是一个窗口的根句柄,每个窗口的部件也是有窗口句柄的,称为子窗口句柄。
获取到根窗口句柄时,可以通过win32gui.EnumChildWindows方法来获取子窗口句柄。
测试代码:
这时,就看到了通过第二种方法获取到的是子窗口句柄,通过第一种方法获取到的是根窗口句柄。
注意:win32gui.EnumChildWindows会获取到所有的子窗口句柄,无论是子窗口句柄,还是子句柄的子句柄,都能获取到。
还可以通过一些工具来获取窗口的信息,最常用的软件有spy++