python-uiautomation-for-windows

repository·master·Indexed 25 days ago

https://github.com/yinkaisheng/python-uiautomation-for-windows

A Python module that wraps Microsoft's UIAutomation API to automate Windows applications, including Win32, WPF, Qt, Chrome, and Electron apps. It provides tools for traversing UI control trees, searching for controls using parameters like Name, ClassName, and AutomationId, and managing control existence via Refind() and Exists(). Includes a CLI tool, automation.py, for inspecting the UI tree of running applications.

Tokens
1.8K
Snippets
6
Records
12
Agent score
36%

What's inside uiautomation

  1. Optimize control search performance

    master

    Searching the entire tree from the root is inefficient. Instead, use hierarchical searching by specifying searchDepth at each level to narrow down the search space quickly.

    # Efficient hierarchical search
    window2 = uiautomation.WindowControl(searchDepth=1, Name='window2')
    sub = window2.Control(searchDepth=1, Name='2-4')
    edit = sub.EditControl(searchDepth=1, Name='myedit2')
    edit.SendKeys('hi')
  2. Configure Chrome and Electron apps for UIAutomation

    master

    Chrome and Electron-based applications require a specific startup flag to enable UIAutomation support. Add the following argument when launching the application:

    --force-renderer-accessibility

  3. Search for UI controls efficiently

    master

    When searching for controls, it is significantly faster to find a top-level window first and then search for its children, rather than searching from the root (Desktop) with a large searchDepth.

    Inefficient approach: Searching from the root with a high searchDepth forces the library to traverse every control in the tree up to that depth.

    Efficient approach:

    1. Find the WindowControl using searchDepth=1.
    2. Find the child Control from that window object.
    3. Find the specific target control (e.g., EditControl) from the child object.
    # Efficient way to find a nested control
    window2 = uiautomation.WindowControl(searchDepth=1, Name='window2')
    sub = window2.Control(searchDepth=1, Name='2-4')
    edit = sub.EditControl(searchDepth=1, Name='myedit2')
    edit.SendKeys('hi')
  4. Install uiautomation via pip

    master

    You can install the uiautomation module using pip.

    Note on Python versions: Do not use Python 3.7.6 or 3.8.1, as comtypes does not work in these versions. Use an earlier or the latest version of Python.

    Note on Permissions: You should run Python as administrator. Otherwise, uiautomation may fail to enumerate controls or retrieve control information on Windows 7 or higher.

    pip install uiautomation
  5. Handle control existence and re-searching

    master

    When a control's underlying COM object (Control.Element) becomes invalid (e.g., after a window closes or refreshes), you must trigger a re-search.

    • Control.Exists(maxSearchSeconds, searchIntervalSeconds): Checks if a control exists without throwing an exception. This also triggers a re-search if the element is invalid.
    • Control.Refind(): Explicitly invalidates the current element to trigger a re-search on the next operation.
    • LookupError: Thrown if a control is not found within uiautomation.TIME_OUT_SECOND (default 10s).
  6. Initialize and search for controls

    master

    Use uiautomation.GetRootControl() to get the Desktop root. To find specific controls, use specialized Control classes (e.g., WindowControl, EditControl, ButtonControl) with search criteria.

    Search Parameters for Control initialization:

    • searchFromControl: The control to start searching from (defaults to Desktop).
    • searchDepth: Search within 1 to searchDepth layers of descendants.
    • Depth: Search only at the exact depth specified.
    • foundIndex: The index of the matching control (starting from 1).
    • Name: The control's name.
    • SubName: Partial name match.
    • RegexName: Name matching via regular expression.
    • ClassName: The control's class name.
    • AutomationId: The control's AutomationId.
    • ControlType: The type of control.
    • Compare: A custom function function(control: Control, depth: int) -> bool for complex matching.
  7. Manage control existence and re-finding

    master

    The Control.Element property holds the low-level COM object. If Control.Element is None, uiautomation will attempt to search for the control using the provided properties when you call a method or property.

    • Control.Exists(maxSearchSeconds, searchIntervalSeconds): Checks if a control exists without raising exceptions.
    • Control.Refind(): Invalidates the current Control.Element and forces a new search the next time the control is used.
    • LookupError: Raised if a control cannot be found within the global search timeout (default 10 seconds).
    • SetGlobalSearchTimeout(seconds): Sets the global timeout for searches.

    Important: If a window or control is closed (e.g., via GetWindowPattern().Close()), the existing control objects become invalid and you must use Refind() or Exists() to trigger a new search.

    import uiautomation as auto
    
    # Set global timeout
    auto.uiautomation.SetGlobalSearchTimeout(15)
    
    # Check existence without exception
    if window.Exists(3, 1):
        # Trigger a new search for an invalid control
        window.Refind()
        edit.Refind()
  8. Control search parameters

    master

    When creating a control object (e.g., WindowControl, EditControl), you can specify several parameters to filter the search. These are passed to the underlying __init__ method of the Control class.

    Available Search Parameters:

    • searchFromControl: The control to start searching from (defaults to None).
    • searchDepth: How deep to search in the tree (default is 0xFFFFFFFF).
    • searchInterval: The interval between search attempts.
    • foundIndex: The index of the found control (e.g., foundIndex=2 for the second matching control).
    • Name: The name of the control.
    • SubName: The sub-name of the control.
    • RegexName: A regular expression to match the name.
    • ClassName: The class name of the control.
    • AutomationId: The automation ID.
    • ControlType: The type of control.
    • Depth: The depth of the control.
    • Compare: A lambda function for custom search logic (e.g., lambda c, d: c.Name in ['Close', '关闭']).
  9. Use automation.py to traverse UI controls

    master

    After installation, an automation.py script is available in your Python Scripts directory (e.g., C:\PythonXX\Scripts\). You can use this CLI tool to inspect the UI tree of running applications.

    Common commands:

    • automation.py -h: Show help.
    • automation.py -t 0 -n: Print the current active window's controls, showing their full names.
    • automation.py -r -d 1 -t 0: Print the desktop (the root of the control tree) and its top-level children (windows).
  10. Run automation.py to enumerate control tree

    master

    The automation.py script (found in your Python Scripts directory or the source root) is used to inspect the UI control tree. Use these commands to find control properties and patterns for your automation code:

    • automation.py -h: View command help.
    • automation.py -t 0: Print all controls in the currently active window.
    • automation.py -r -d 1 -t 0: Print the Desktop (root) and its first layer of top-level windows.
    automation.py -h