UIAutomation操作程序时会给程序发送WM_GETOBJECT消息,如果程序处理WM_GETOBJECT消息,实现UI Automation Provider,并调用函数
UiaReturnRawElementProvider(HWND hwnd,WPARAM wparam,LPARAM lparam,IRawElementProviderSimple *el),此程序就支持UIAutomation。
IRawElementProviderSimple 就是 UI Automation Provider,包含了控件的各种信息,如Name,ClassName,ContorlType,坐标等。
UIAutomation 根据程序返回的 IRawElementProviderSimple,就能遍历程序的控件,得到控件各种属性,进行自动化操作。若程序没有处理WM_GETOBJECT或没有实现UIAutomation Provider,UIAutomation则无法识别这些程序内的控件,不支持自动化。
很多DirectUI程序没有实现UIAutomation Provider,所以不支持自动化。
关于各控件所支持的控件模式,可参考:
https://docs.microsoft.com/zh-cn/windows/win32/winauto/uiauto-controlpatternmapping
pip install uiautomation
①获取窗口
import uiautomation as auto
# 前提是打开记事本-打开操作不在这里叙述
window_name = auto.WindowControl(searchDepth=1, ClassName="Notepad") # 获取窗口
# 设置窗口前置
window_name.SetTopmost(True)
print(window_name.Name)
控件可用参数说明:
searchFromControl = None:从哪个控件开始查找,如果为None,从根控件Desktop开始查找
searchDepth = 0xFFFFFFFF: 搜索深度
searchInterval = SEARCH_INTERVAL:搜索间隔
foundIndex = 1 :搜索到的满足搜索条件的控件索引,索引从1开始
Name:控件名字
SubName :控件部分名字
RegexName:使用re.match匹配符合正则表达式的名字,Name,SubName,RegexName只能使用一个,不能同时使用
ClassName :类名字
AutomationId: 控件AutomationId
AutomationIdControlType :控件类型
Depth:控件相对于searchFromControl的精确深度
Compare:自定义比较函数function(control: Control, depth: int)->bool
为了进一步操作该程序,我们可以使用inspect.exe工具分析控件结构
②UIAutomation的常见功能
显示桌面(相当于点击桌面右下角的按钮):
auto.ShowDesktop()
获取uiautomation已运行的时间:
auto.ProcessTime()
判断两个控件是否一致:
auto.ControlsAreSame(control1, control2)
鼠标点击指定坐标:
auto.Click(x, y)
右键单击:
auto.RightClick(x, y)
鼠标拖拽(鼠标从(x1,y1)位置按下鼠标拖动到(x2,y2)位置):
auto.DragDrop(x1, y1, x2, y2, moveSpeed=1) # moveSpeed参数决定了移动的速度。
隐藏窗口:
win.Hide(0)
显示窗口:
win.Show(0)
窗口最小化:
win.Minimize()
窗口最大化:
win.Maximize()
判断窗口是否已经被最小化:
auto.IsIconic(win.NativeWindowHandle) # IsIconic进支持传入本地窗口句柄。
管理员提权
# 将原本存在于__main__代码块中的内容存放于main()方法中即可
if __name__ =='__main__':
if auto.IsUserAnAdmin():
main()
else:
print('RunScriptAsAdmin', sys.executable, sys.argv)
auto.RunScriptAsAdmin(sys.argv)