python篇-pywinauto使用-PC端应用UI自动化

1- pywinauto 中的uia是什么意思?

在pywinauto库中,uia指的是UI Automation,这是Windows操作系统提供的一种技术框架,用于实现用户界面(UI)的自动化测试和辅助功能访问。UI Automation是微软从Windows Vista开始引入的核心技术,旨在为所有UI元素提供一致的编程接口,无论这些元素是由何种技术(如Win32、WPF、UWP等)实现的。

在pywinauto中,通过指定backend="uia",用户可以选择使用UI Automation作为底层引擎来与应用程序的UI元素进行交互。这为自动化测试提供了更广泛的支持,尤其是在处理现代Windows应用(尤其是使用WPF和UWP技术构建的应用)时更为有效。UI Automation后端相比传统的win32后端,提供了更丰富和高级的元素属性、控制模式(Control Patterns)以及事件支持,使得自动化脚本可以更加灵活和强大。

使用UI Automation后端,开发者可以更容易地定位和操作UI元素,如获取元素的属性、模拟鼠标和键盘操作、监听UI事件等,这对于创建复杂的自动化测试场景尤其有用。

2-pywinauto 中main_window.child_window()方法及参数详细介绍

parent_window.child_window(arguments)

其中,parent_window是你已经获取到的窗口对象,arguments是用于筛选子窗口的一系列关键字参数。

参数详解
child_window()方法接受多个关键字参数来精确地定位子窗口,常见的参数包括但不限于:

title: 字符串,控件的标题或文本。
class_name: 字符串,控件的类名。
control_type: 字符串,控件的类型(仅在UIA backend下有效)。
auto_id: 字符串,控件的自动化ID(AutomationId)。
name: 字符串,控件的名称属性,可能与标题或自动化ID不同。
backend: 字符串,指定后端类型,如 'win32' 或 'uia',默认自动选择。
process: 整数,指定目标窗口所在的进程ID。
enabled: 布尔值,是否只查找启用的控件。
visible: 布尔值,是否只查找可见的控件。
top_level_only: 布尔值,是否只在顶级窗口中查找。
found_index: 整数,当找到多个匹配项时,可以选择特定索引的匹配项。
control_id: 整数,控件的ID(Windows API中的控件ID)。
handle: 整数或ctypes.c_void_p,直接指定控件的句柄。
regex_title: 正则表达式对象或字符串,用于匹配标题的正则表达式。
regex_class_name: 同上,但用于匹配类名的正则表达式。
best_match: 字符串,用于best_match()逻辑,尝试匹配最接近的控件。

3-pywinauto 定位元素

方法一:1.可使用 inspect.exe来

方法二:这里我使用 dump_tree() 方法可以获取窗口的详细信息,包括控件的层次结构和属性。

print(dlgmax.dump_tree())

层次结构和属性如下

Dialog - 'XXXXXXX信息管理系统'    (L579, T265, R1340, B775)
['XXXXXXX信息管理系统', 'Dialog', 'XXXXXXX信息管理系统Dialog', 'XXXXXXX信息管理系统0', 'XXXXXXX信息管理系统1']
child_window(title="XXXXXXX信息管理系统", auto_id="LoginForm", control_type="Window")
   | 
   | Button - '忘记密码'    (L1034, T674, R1096, B697)
   | ['忘记密码Button', 'Button', '忘记密码', 'Button0', 'Button1']
   | child_window(title="忘记密码", auto_id="btn_repwd", control_type="Button")
   | 
   | Edit - ''    (L855, T563, R1096, B582)
   | ['', 'Edit', '0', '1', 'Edit0', 'Edit1']
   | child_window(auto_id="tb_password", control_type="Edit")
   | 
   | Edit - '密码'    (L855, T513, R1096, B532)
   | ['2', 'Edit2']
   | child_window(title="密码", auto_id="tb_account", control_type="Edit")
   | 
   | Static - '密码'    (L810, T564, R849, B588)
   | ['密码', 'Static', '密码Static', 'Static0', 'Static1']
   | child_window(title="密码", auto_id="pwdTitleLbl", control_type="Text")
   | 
   | Static - '账号'    (L810, T514, R849, B538)
   | ['Static2', '账号Static', '账号']
   | child_window(title="账号", auto_id="accountTitleLbl", control_type="Text")
   | 
   | Button - '登录'    (L810, T631, R1096, B661)
   | ['登录Button', '登录', 'Button2']
   | child_window(title="登录", auto_id="btn_login", control_type="Button")
   | 

从上面可以得出登录的元素;这样就完成登录界面的UI自动化代码了

    account=dlgmax.child_window(auto_id ="tb_account", control_type="Edit")
    account.type_keys("admin")
    pwd=dlgmax.child_window(auto_id = "tb_password", control_type = "Edit")
    pwd.type_keys("888888")
    dlgmax.child_window(title="登录",auto_id="btn_login", control_type="Button").click_input()

4-pywinauto 没有权限打开PC端应用,怎么解决?

raise AppStartError(message) pywinauto.application.AppStartError: Could not create the process "C:\Program Files (x86)\aaaa\xxxxxx信息管理系统\ybbbb.exe" Error returned by CreateProcess: (740, 'CreateProcess', '请求的操作需要提升。')

确保脚本本身以管理员身份运行

def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False
if not is_admin():
    # 重新启动脚本以管理员身份运行
    ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
    sys.exit(0)

整体代码如下

import subprocess
from pywinauto import Application
import time
import ctypes
import sys
import io
def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False
if not is_admin():
    # 重新启动脚本以管理员身份运行
    ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
    sys.exit(0)
try:
    # 将标准输出重定向到文件
    output_file = open('output.txt', 'w', encoding='utf-8')
    sys.stdout = output_file

    # 打开应用
    app = Application(backend="uia").start(r'C:\Program Files (x86)\aaaaa\xxxxx管理系统\bbbb.exe')
    print("应用启动成功")
    # 等待主窗口出现
    time.sleep(10)  # 增加等待时间
    dlgmax = app["xxxxxxx管理系统"]
    if dlgmax.exists():
        print("主窗口已找到")
    else:
        print("主窗口未找到")
        raise Exception("主窗口未找到")
    print(dlgmax.dump_tree())
    account=dlgmax.child_window(auto_id ="tb_account", control_type="Edit")
    account.type_keys("admin")
    pwd=dlgmax.child_window(auto_id = "tb_password", control_type = "Edit")
    pwd.type_keys("888888")
    dlgmax.child_window(title="登录",auto_id="btn_login", control_type="Button").click_input()
    # print(dlgmax.dump_tree())
except Exception as e:
    print(f"Error: {e}")
finally:
    # 恢复标准输出,并确保使用 UTF-8 编码
    output_file.close()
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
    input("按回车键退出...")

作者:weixin_42811974

物联沃分享整理
物联沃-IOTWORD物联网 » python篇-pywinauto使用-PC端应用UI自动化

发表回复