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()