Python UIAutomation for Windows - comprehensive library for automating Windows applications using Microsoft's UIAutomation framework
Core functionality for finding, accessing, and managing UI controls within the Windows control tree. These functions provide the foundation for all automation operations by enabling discovery and traversal of the UI hierarchy.
Functions to access top-level system controls and entry points into the UI hierarchy.
def GetRootControl() -> Control:
"""
Get the desktop root control (top of the control tree).
Returns:
Control: Desktop control representing the root of all UI elements
"""
def GetFocusedControl() -> Control:
"""
Get the currently focused control.
Returns:
Control: The control that currently has keyboard focus, or None if none
"""
def GetForegroundControl() -> Control:
"""
Get the foreground window control.
Returns:
Control: The control representing the currently active window
"""
def GetConsoleWindow() -> Control:
"""
Get the console window control.
Returns:
Control: The control representing the console window
"""Find controls based on screen coordinates, useful for mouse-driven automation scenarios.
def ControlFromPoint(x: int, y: int) -> Control:
"""
Get the control at the specified screen coordinates.
Args:
x: X coordinate in screen pixels
y: Y coordinate in screen pixels
Returns:
Control: The control at the specified point, or None if none found
"""
def ControlFromPoint2(x: int, y: int) -> Control:
"""
Alternative method to get control at screen coordinates.
Args:
x: X coordinate in screen pixels
y: Y coordinate in screen pixels
Returns:
Control: The control at the specified point, or None if none found
"""
def ControlFromCursor() -> Control:
"""
Get the control under the current mouse cursor position.
Returns:
Control: The control under the cursor, or None if none found
"""
def ControlFromCursor2() -> Control:
"""
Alternative method to get control under cursor.
Returns:
Control: The control under the cursor, or None if none found
"""Access controls using Windows handles for interoperability with other Windows APIs.
def ControlFromHandle(handle: int) -> Control:
"""
Get a control from its window handle.
Args:
handle: Windows handle (HWND) of the control
Returns:
Control: Control wrapper for the window handle, or None if invalid
"""Advanced search functions for finding controls based on property criteria.
def FindControl(control: Control, compareFunc: callable, maxDepth: int = 0xFFFFFFFF,
findFromSelf: bool = False, foundIndex: int = 1) -> Control:
"""
Find a control using a comparison function.
Args:
control: Root control to start search from
compareFunc: Function that takes (control, depth) and returns True/False
maxDepth: Maximum depth to search (default: unlimited)
findFromSelf: Whether to include the root control in search
foundIndex: Which match to return (1-based index)
Returns:
Control: Matching control found, or None if no match
"""
def ControlsAreSame(control1: Control, control2: Control) -> bool:
"""
Check if two control references point to the same UI element.
Args:
control1: First control to compare
control2: Second control to compare
Returns:
bool: True if controls represent the same UI element
"""Functions for walking and analyzing the UI control hierarchy.
def WalkControl(control: Control, includeTop: bool = False, maxDepth: int = 0xFFFFFFFF) -> None:
"""
Walk the control tree starting from the given control.
Args:
control: Root control to start walking from
includeTop: Whether to include the root control in iteration
maxDepth: Maximum depth to traverse (default: unlimited)
"""
def WalkTree(root: Control, depth: int, callback: callable) -> None:
"""
Walk the control tree to a specified depth.
Args:
root: Root control to start from
depth: Maximum depth to traverse
callback: Function called for each control visited
"""Functions for waiting and timing control operations.
def WaitForExist(control: Control, timeout: float) -> bool:
"""
Wait for a control to exist/appear.
Args:
control: Control to wait for
timeout: Maximum time to wait in seconds
Returns:
bool: True if control exists, False if timeout
"""
def WaitForDisappear(control: Control, timeout: float) -> bool:
"""
Wait for a control to disappear/become unavailable.
Args:
control: Control to wait for disappearance
timeout: Maximum time to wait in seconds
Returns:
bool: True if control disappeared, False if timeout
"""
def SetGlobalSearchTimeOut(seconds: float) -> None:
"""
Set the global timeout for control search operations.
Args:
seconds: Timeout value in seconds
"""import uiautomation
# Get the desktop root and enumerate top-level windows
root = uiautomation.GetRootControl()
for window in root.GetChildren():
print(f"Window: {window.Name}")
# Find a specific application window
calculator = uiautomation.FindControl(root, Name='Calculator', ControlType=uiautomation.ControlType.WindowControl)
# Get the currently active window
active_window = uiautomation.GetForegroundControl()
print(f"Active window: {active_window.Name}")# Get control at specific screen coordinates
control_at_point = uiautomation.ControlFromPoint(100, 200)
if control_at_point:
print(f"Control at (100,200): {control_at_point.Name}")
# Get control under current cursor position
cursor_control = uiautomation.ControlFromCursor()
if cursor_control:
print(f"Control under cursor: {cursor_control.Name}")# Wait for a button to appear
ok_button = uiautomation.ButtonControl(Name='OK')
if uiautomation.WaitForExist(ok_button, 10):
ok_button.Click()
else:
print("OK button did not appear within 10 seconds")
# Wait for a dialog to disappear
dialog = uiautomation.WindowControl(Name='Progress Dialog')
if dialog.Exists():
disappeared = uiautomation.WaitForDisappear(dialog, timeout=30)
if disappeared:
print("Dialog closed successfully")# Use hierarchical search for better performance
# Instead of searching the entire tree:
# button = uiautomation.ButtonControl(searchDepth=10, Name='Submit')
# Use parent-child relationships:
app_window = uiautomation.WindowControl(searchDepth=1, Name='MyApp')
dialog = app_window.WindowControl(searchDepth=1, Name='Settings')
submit_button = dialog.ButtonControl(searchDepth=2, Name='Submit')Install with Tessl CLI
npx tessl i tessl/pypi-uiautomation