pywinauto 脚本制作
一 、获取窗口句柄
首先获取句柄,其次扫描组件,然后对按钮和文本进行操作
安装依赖
pip install pywin32 -i https://pypi.doubanio.com/simple
扫描全部的句柄
import win32gui
# GetDesktopWindow 获得代表整个屏幕的一个窗口(桌面窗口)句柄
hd = win32gui.GetDesktopWindow()
# 获取所有子窗口
hwndChildList = []
win32gui.EnumChildWindows(hd, lambda hwnd, param: param.append(hwnd), hwndChildList)
for hwnd in hwndChildList:
print("句柄:", hwnd, "标题:", win32gui.GetWindowText(hwnd))
# f.write("句柄:" + str(hwnd) + " 标题:" + win32gui.GetWindowText(hwnd) + '\n'
将句柄写入文本
lst = [1, 2, 3]
str_lst = [str(item) for item in lst]
# 假设有一个列表
my_list = ['这', '是', '一个', '测试']
# 将列表中的每个元素转换为字符串,并用换行符连接
list_as_string = '\n'.join(my_list)
# 打开文件进行写入
with open('output.txt', 'w', encoding='utf-8') as file:
file.write(list_as_string)
最终写入
def find_all_window():
hd = win32gui.GetDesktopWindow()
# 获取所有子窗口
hwnd_child_list = []
win32gui.EnumChildWindows(hd, lambda hwnd, param: param.append(hwnd), hwnd_child_list)
str_list = []
for hwnd in hwnd_child_list:
print("句柄:", hwnd, "标题:", win32gui.GetWindowText(hwnd))
str_list.append("句柄:" + str(hwnd)+"标题:" + win32gui.GetWindowText(hwnd))
# f.write("句柄:" + str(hwnd) + " 标题:" + win32gui.GetWindowText(hwnd) + '\n'
# 将句柄生成文件
list_as_string = '\n'.join(str_list)
# 打开文件进行写入
with open('output.txt', 'w', encoding='utf-8') as file:
file.write(list_as_string)
在文件中查询到
句柄:267410标题:
句柄:1905680标题:
句柄:1512536标题:Import Excel File V1.0
句柄:332172标题:
句柄:70010标题:
句柄:70002标题:CWebviewHostWnd
句柄:70004标题:
句柄:70018标题:Chrome Legacy Window
其中Import Excel File V1.0的句柄为
句柄:1512536标题:Import Excel File V1.0
使用句柄查找应用窗口, 并前置
# 将查询的窗口前置,handle是句柄
def preposition_windows(handle):
hwnd = win32gui.FindWindow(0, win32gui.GetWindowText(handle)) # 寻找窗口
if not hwnd:
print("找不到该窗口")
else:
win32gui.SetForegroundWindow(hwnd) # 前置窗口
完整代码
import win32gui
import win32con
import pyautogui
from pynput import keyboard, mouse
from loguru import logger
from threading import Thread
import time
import re
from openpyxl import load_workbook
from openpyxl import Workbook
from openpyxl import styles
from openpyxl.styles import *
import pandas as pd
import string
import re
import os
import datetime
def find_all_window():
hd = win32gui.GetDesktopWindow()
# 获取所有子窗口
hwnd_child_list = []
win32gui.EnumChildWindows(hd, lambda hwnd, param: param.append(hwnd), hwnd_child_list)
str_list = []
for hwnd in hwnd_child_list:
print("句柄:", hwnd, "标题:", win32gui.GetWindowText(hwnd))
str_list.append("句柄:" + str(hwnd)+"标题:" + win32gui.GetWindowText(hwnd))
# f.write("句柄:" + str(hwnd) + " 标题:" + win32gui.GetWindowText(hwnd) + '\n'
# 将句柄生成文件
list_as_string = '\n'.join(str_list)
# 打开文件进行写入
with open('output.txt', 'w', encoding='utf-8') as file:
file.write(list_as_string)
# 将查询的窗口前置,handle是句柄
def preposition_windows(handle):
hwnd = win32gui.FindWindow(0, win32gui.GetWindowText(handle)) # 寻找窗口
if not hwnd:
print("找不到该窗口")
else:
win32gui.SetForegroundWindow(hwnd) # 前置窗口
# 通过名字查询句柄
# hwnd = win32gui.FindWindow(None, "窗口标题")
if __name__ == '__main__':
# 查询所有窗口,当名字查不到句柄时,使用
# find_all_window()
# 函数
hwnd = win32gui.FindWindow(None, "frm_ImportExcel")
# 显示窗口
# win32gui.ShowWindow(hwnd, win32con.SW_SHOW)
# win32gui.SetForegroundWindow(hwnd) # 前置窗口
handle = 1643806
前置窗口
preposition_windows(handle)
注意
应用名称和窗口名称不同
通过窗口名称返回句柄(最好的方法)
import win32gui
import win32con
if __name__ == '__main__':
# 查询所有窗口,当名字查不到句柄时,使用
# find_all_window()
# 函数
hwnd = win32gui.FindWindow(None, "frm_ImportExcel")
# 显示窗口
win32gui.ShowWindow(hwnd, win32con.SW_SHOW)
win32gui.SetForegroundWindow(hwnd) # 前置窗口
print(hwnd)
二、查询窗口的控件
#Only for Windows!!!!
import win32gui as wg #pip install pypiwin32
result = []
handle = wg.FindWindow(classname, name) #classname是窗口类名,name是窗口名,可以只写一个,另一个为None,也可以两个都写
def callback(handle, res):
result.append(handle)
return True
wg.EnumChildWindows(handle, callback, None)
#result就是控件名
获取树形控件的句柄
获取活动窗口的句柄
# 获取当前活动窗口句柄
hParent = win32gui.GetForegroundWindow()
# 获取TreeView句柄
hTreeView = win32gui.FindWindowEx(hParent, 0, "SysTreeView", None)
# 获取选中项的标题
selectedIndex = win32gui.SendMessage(hTreeView, win32con.TVM_GETNEXTITEM, win32con.TVGN_CARET, 0)
title = win32gui.SendMessage(hTreeView, win32con.TVM_GETITEMTEXT, selectedIndex, buffer)
测试连接
# 验证是否找到窗口
win32gui.ShowWindow(hwnd, win32con.SW_SHOW)
win32gui.SetForegroundWindow(handle) # 前置窗口
在这段代码中,selectedIndex是选中项的索引,title是选中项的标题。win32gui.SendMessage函数用于发送消息给TreeView控件,win32con.TVM_GETNEXTITEM和win32con.TVM_GETITEMTEXT是获取下一个项和获取项文本的消息常量。win32con.TVGN_CARET表示获取当前选中项的常量
通过spy++获取类名,然后通过
# 获取TreeView类名获取句柄
hTreeView = win32gui.FindWindowEx(hParent, 0, "SysTreeView", None)
初识UI自动化(inspect.exe + uiautomation)
https://blog.csdn.net/knighthood2001/article/details/124297008
UI Spy.exe 快速获取窗口或控件的属性信息(免C币免积分下载)
https://blog.csdn.net/weixin_39927850/article/details/126243682
Python UI自动化-UIAutomation之Inspect下载
https://blog.csdn.net/weixin_52770263/article/details/129957439
三、pywinauto元素定位和操控(联合inspect.exe)
教程
pywinauto
https://blog.csdn.net/weixin_42753043/article/details/123962834
PC端windows自动化:pywinauto(一)安装和打开程序
https://blog.csdn.net/m0_67761286/article/details/128014397
下载 pywinauto对控件进行操作
pip install pywinauto -i https://pypi.doubanio.com/simple
导入依赖
from pywinauto import Application
from pywinauto import findwindows
查询软件句柄
通过inpect.exe查出软件属性如下
name = frm_ImportExcel
class_name = Tfrm_ImportExcel
代码连接软件如下
# 连接app,通过窗口名称
handle = win32gui.FindWindow(None, "frm_ImportExcel")
# 使用uia模式,访问更多的标签
app = Application(backend="uia").connect(handle=handle)
测试连接
# 验证是否找到窗口
win32gui.ShowWindow(hwnd, win32con.SW_SHOW)
win32gui.SetForegroundWindow(handle) # 前置窗口
操控树组件
查询窗口
app.top_window() # 返回应用程序当前顶部窗口,是WindowSpecification对象,可以继续使用对象的方法往下继续查找控件
# eg:如:app.top_window().child_window(title='地址和搜索栏', control_type='Edit')
app.window(**kwargs) # 根据筛选条件,返回一个窗口, 是WindowSpecification对象,可以继续适用对象的方法往下继续查找控件
# eg: 微信主界面 app.window(class_name='WeChatMainWndForPC')
app.windows(**kwargs) # 根据筛选条件返回一个窗口列表,无条件默认全部,列表项为wrapped(装饰器)对象,可以使用wrapped对象的方法,注意不是WindowSpecification对象
# eg:[<uiawrapper.UIAWrapper - '李渝的早报 - Google Chrome', Pane, -2064264099699444098>]
app.kill(soft=False) # 强制关闭
app.cpu_usage() # 返回指定秒数期间的CPU使用率百分比
app.wait_cpu_usage_lower(threshold=2.5, timeout=None, usage_interval=None) # 等待进程CPU使用率百分比小于指定的阈值threshold
app.is64bit() # 如果操作的进程是64-bit,返回True
查询元素
# 查询app窗口,通过窗口名
dlg = app["frm_ImportExcel"]
# dlg.print_control_identifiers()
# 查询树
tree_view = dlg.child_window(class_name='TRzTreeView')
# 展开树节点
# 画方框圈住元素
tree_view.draw_outline()
#tree_view.print_control_identifiers()
# 选择零售销货单
tree_view.child_window(title="[80802003]零售退货单", control_type="TreeItem").select()
在窗口下继续查询组件
完整代码 pywinauto
import win32gui
import win32con
import win32api
import pyautogui
from pynput import keyboard, mouse
from loguru import logger
from threading import Thread
import time
import re
from openpyxl import load_workbook
from openpyxl import Workbook
from openpyxl import styles
from openpyxl.styles import *
import pandas as pd
import string
import re
import os
import datetime
import time
from pywinauto import Application
from pywinauto import findwindows
def find_all_window():
hd = win32gui.GetDesktopWindow()
# 获取所有子窗口
hwnd_child_list = []
win32gui.EnumChildWindows(hd, lambda hwnd, param: param.append(hwnd), hwnd_child_list)
str_list = []
for hwnd in hwnd_child_list:
print("句柄:", hwnd, "标题:", win32gui.GetWindowText(hwnd))
str_list.append("句柄:" + str(hwnd) + "标题:" + win32gui.GetWindowText(hwnd))
# f.write("句柄:" + str(hwnd) + " 标题:" + win32gui.GetWindowText(hwnd) + '\n'
# 将句柄生成文件
list_as_string = '\n'.join(str_list)
# 打开文件进行写入
with open('output.txt', 'w', encoding='utf-8') as file:
file.write(list_as_string)
# 将查询的窗口前置,handle是句柄
def preposition_windows(handle):
hwnd = win32gui.FindWindow(0, win32gui.GetWindowText(handle)) # 寻找窗口
if not hwnd:
print("找不到该窗口")
else:
win32gui.SetForegroundWindow(hwnd) # 前置窗口
def find_control(handle):
result = []
# class_name是窗口类名,name是窗口名,可以只写一个,另一个为None,也可以两个都写
# handle = wg.FindWindow(class_name, name)
def callback(handle, res):
result.append(str(handle) + ": " + win32gui.GetWindowText(handle))
return True
win32gui.EnumChildWindows(handle, callback, None)
return result
# result就是控件名
if __name__ == '__main__':
# 查询所有窗口,当名字查不到句柄时,使用
# find_all_window()
# 连接app,通过窗口名称
handle = win32gui.FindWindow(None, "frm_ImportExcel")
# 使用uia模式,访问更多的标签
app = Application(backend="uia").connect(handle=handle)
# 验证是否找到窗口
win32gui.ShowWindow(handle, win32con.SW_SHOW)
win32gui.SetForegroundWindow(handle) # 前置窗口
# time.sleep(2)
# 查询app窗口,通过窗口名
dlg = app["frm_ImportExcel"]
# dlg.print_control_identifiers()
# 查询树
tree_view = dlg.child_window(class_name='TRzTreeView')
# 展开树节点
# 画方框圈住元素
tree_view.draw_outline()
#tree_view.print_control_identifiers()
# 选择零售销货单
tree_view.child_window(title="[80802003]零售退货单", control_type="TreeItem").select()
# 等待元素加载
time.sleep(2)
# 查找工具栏
tool_bar = dlg.child_window(class_name='TToolBar')
# 画方框圈住元素
tool_bar.draw_outline()
# 展开组件
tool_bar.print_control_identifiers()
# 点击新增
tree_view.child_window(title="[80802003]零售退货单", control_type="TreeItem").select()
tool_bar.child_window(title="新增", control_type="Button").click_input()
# 输入信息
# 点击导入
time.sleep(1)
tool_bar.child_window(title="导入", control_type="Button").click_input()
time.sleep(2)