93 lines
3.6 KiB
Python
93 lines
3.6 KiB
Python
import uiautomation as auto
|
||
import subprocess
|
||
import time
|
||
import yaml
|
||
|
||
class AutomationEngine:
|
||
def __init__(self, config_path):
|
||
with open(config_path, 'r', encoding='utf-8') as f:
|
||
self.config = yaml.safe_load(f)
|
||
self.window = None
|
||
|
||
def find_control(self, parent, selector_dict):
|
||
"""根据字典动态查找控件"""
|
||
if not selector_dict:
|
||
return parent
|
||
|
||
args = selector_dict.copy()
|
||
|
||
# 1. 提取 ControlType,例如 "MenuItemControl"
|
||
# 如果 YAML 里没写,默认用 generic 的 Control
|
||
control_type = args.pop('ControlType', 'Control')
|
||
|
||
# 2. 动态获取查找方法,例如 parent.MenuItemControl(...)
|
||
# 这样比直接用 parent.Control(ControlType=...) 更符合库的设计
|
||
if hasattr(parent, control_type):
|
||
finder_method = getattr(parent, control_type)
|
||
else:
|
||
print(f"警告: 未知的 ControlType '{control_type}',回退到通用查找。")
|
||
finder_method = parent.Control
|
||
# 如果回退,需要把 ControlType 加回去作为属性过滤
|
||
if control_type != 'Control':
|
||
args['ControlType'] = control_type
|
||
|
||
# 3. 执行查找
|
||
return finder_method(**args)
|
||
|
||
def run(self):
|
||
print(f"开始执行任务: {self.config['name']}")
|
||
|
||
subprocess.Popen(self.config['app'])
|
||
time.sleep(1) # 等待启动
|
||
|
||
# 查找主窗口
|
||
self.window = auto.WindowControl(**self.config['target_window'])
|
||
if not self.window.Exists(5):
|
||
raise Exception("❌ 主窗口未找到,请检查 ClassName 是否正确 (Win11记事本可能是 'Notepad' 但内部结构不同)")
|
||
|
||
self.window.SetTopmost(True)
|
||
print(f"✅ 锁定主窗口: {self.window.Name}")
|
||
|
||
for i, step in enumerate(self.config['steps']):
|
||
action = step.get('action')
|
||
desc = step.get('desc', action)
|
||
print(f"\n--- 步骤 {i+1}: {desc} ---")
|
||
|
||
# 确定父级
|
||
target_control = self.window
|
||
if 'parent' in step:
|
||
# 弹窗通常是顶层窗口,从 Root 找,searchDepth=1 表示只查桌面的一级子窗口
|
||
target_control = self.find_control(auto.GetRootControl(), step['parent'])
|
||
|
||
# 确定目标控件
|
||
if 'selector' in step:
|
||
target_control = self.find_control(target_control, step['selector'])
|
||
|
||
# !!! 关键调试信息 !!!
|
||
# 检查控件是否存在,如果不存在,打印详细信息并停止
|
||
if not target_control.Exists(3):
|
||
print(f"❌ 错误: 无法找到控件!")
|
||
print(f" 查找参数: {step.get('selector')}")
|
||
print(f" 父级控件: {target_control.GetParentControl()}")
|
||
# 可以在这里抛出异常停止脚本,方便调试
|
||
break
|
||
|
||
# 执行动作
|
||
if action == 'input':
|
||
target_control.Click()
|
||
target_control.SendKeys(step['value'])
|
||
print(f" 输入: {step['value']}")
|
||
|
||
elif action == 'click':
|
||
target_control.Click()
|
||
print(" 点击成功")
|
||
|
||
elif action == 'sleep':
|
||
time.sleep(step['value'])
|
||
print(f" 等待 {step['value']} 秒")
|
||
|
||
print("\n自动化结束")
|
||
|
||
if __name__ == '__main__':
|
||
engine = AutomationEngine(r'D:\project\audoWin\tests\test_case.yaml')
|
||
engine.run() |