You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pywinauto print_control_identifiers()报错:KeyError与COMError求助

问题:pywinauto调用print_control_identifiers()报错排查思路

问题现象

调用print_control_identifiers()查看1С程序窗口元素树时,出现COMError:

Traceback (most recent call last):
  File "C:\formation_uploading__tranco\app\tranco.py", line 170, in run_process
    self.process()
  File "C:\formation_uploading__tranco\app\tranco.py", line 73, in process
    window.print_control_identifiers()
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\application.py", line 624, in print_control_identifiers
    ctrl_names = findbestmatch.get_control_names(ctrl, all_ctrls, txt_ctrls)
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\findbestmatch.py", line 320, in get_control_names
    non_text_names = get_non_text_control_name(control, allcontrols, textcontrols)
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\findbestmatch.py", line 219, in get_non_text_control_name
    ctrl_r = ctrl.rectangle()
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\base_wrapper.py", line 367, in rectangle
    return self.element_info.rectangle
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\uia_element_info.py", line 326, in rectangle
    bound_rect = self._element.CurrentBoundingRectangle
_ctypes.COMError: (-2147220991, 'An event was unable to invoke any of the subscribers', (None, None, None, 0, None))

Process finished with exit code 0

添加depth=3参数时,出现KeyError:

Traceback (most recent call last):
  File "C:\formation_uploading__tranco\app\tranco.py", line 170, in run_process
    self.process()
  File "C:\formation_uploading__tranco\app\tranco.py", line 73, in process
    window.print_control_identifiers(depth=3)
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\application.py", line 616, in print_control_identifiers
    all_ctrls = [this_ctrl, ] + this_ctrl.descendants()
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\base_wrapper.py", line 493, in descendants
    return [self.backend.generic_wrapper_class(element_info) for element_info in desc_elements]
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\base_wrapper.py", line 493, in <listcomp>
    return [self.backend.generic_wrapper_class(element_info) for element_info in desc_elements]
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\controls\uia_controls.py", line 1102, in __init__
    if not self.children() and self.element_info.handle is not None:
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\base_wrapper.py", line 471, in children
    return [self.backend.generic_wrapper_class(element_info) for element_info in child_elements]
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\base_wrapper.py", line 471, in <listcomp>
    return [self.backend.generic_wrapper_class(element_info) for element_info in child_elements]
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\controls\uiawrapper.py", line 186, in __new__
    return super(UIAWrapper, cls)._create_wrapper(cls, element_info, UIAWrapper)
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\base_wrapper.py", line 126, in _create_wrapper
    new_class = cls_spec.find_wrapper(element_info)
  File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pywinauto\controls\uiawrapper.py", line 160, in find_wrapper
    wrapper_match = UiaMeta.control_type_to_cls[element.control_type]
KeyError: None

Process finished with exit code 0

相关代码:

app = Application(backend="uia").connect(title_re="1С:Предприятие - АТК:Управление грузоперевозками")
window = app.window(title_re="1С:Предприятие - АТК:Управление грузоперевозками")
window.set_focus()
button_5 = window.child_window(title="Разобрать", control_type="Button")
button_5.click_input()
button_6 = window.child_window(title="Перечни", control_type="TabItem")
button_6.click_input()
window.print_control_identifiers()

已尝试:添加焦点设置、2-30秒等待、重新获取窗口对象、window.wait('ready', timeout=10)、点击按钮后重新连接应用,均无效。

排查与调试思路

  • 自定义安全遍历函数:自己实现递归遍历控件的逻辑,在获取控件属性(如rectangle、control_type)时捕获COMError和KeyError,跳过异常控件,只输出有效信息。示例逻辑:
    def safe_print_controls(ctrl, indent=0):
        try:
            print(f"{'  '*indent}{ctrl.control_type} - {ctrl.window_text()}")
            for child in ctrl.children():
                safe_print_controls(child, indent+1)
        except (_ctypes.COMError, KeyError):
            print(f"{'  '*indent}[SKIPPED] Invalid control")
    
    safe_print_controls(window)
    
  • 切换backend尝试:将backend从uia改为win32,因为两种backend的控件识别机制不同,win32对部分传统Windows程序兼容性更好。修改代码开头:
    app = Application(backend="win32").connect(title_re="1С:Предприятие - АТК:Управление грузоперевозками")
    
  • 缩小遍历范围:避免遍历整个窗口,先定位到"Перечни"标签对应的内容容器,只遍历该子控件的元素树,减少接触无效控件的概率。例如:
    tab_content = window.child_window(title="Перечни", control_type="TabItem").parent().child_window(control_type="Panel")
    tab_content.print_control_identifiers()
    
  • 升级pywinauto版本:当前使用的pywinauto版本可能存在UIA相关bug,尝试升级到兼容Python3.7的最新版本(如0.6.8),命令:
    pip install --upgrade pywinauto==0.6.8
    
  • 用Inspect.exe分析控件:使用Windows SDK自带的Inspect.exe工具,手动查看目标窗口的控件树,确认是否存在控件类型为None或无法获取边界矩形的控件,定位具体异常控件后,在代码中针对性跳过。
  • 过滤控件类型遍历:调用descendants时指定control_type参数,只遍历已知有效类型的控件,避免触发未知类型的KeyError:
    valid_ctrl_types = ["Button", "Edit", "TabItem", "Panel", "List"]
    for ctrl in window.descendants(control_type=valid_ctrl_types):
        print(ctrl.control_type, ctrl.window_text())
    

内容的提问来源于stack exchange,提问作者ValeraTheSlayer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 06:33:07