Python 3 wrapper of Microsoft UIAutomation. Support UIAutomation for MFC, WindowsForm, WPF, Modern UI(Metro UI), Qt, IE, Firefox, Chrome ...

Overview

The uiautomation module

🇨🇳 中文版介绍

Do not use 3.7.6 and 3.8.1, comtypes doesn't work in these two versions. Install an earlier version or the latest version. https://github.com/enthought/comtypes/issues/202

This module is for UIAutomation on Windows(Windows XP with SP3, Windows Vista, Windows 7 and Windows 8/8.1/10). It supports UIAutomation for the applications which implmented UIAutomation Provider, such as MFC, Windows Form, WPF, Modern UI(Metro UI), Qt(Partly), Firefox(version<=56 or >=60), Chrome and Electron based apps(require --force-renderer-accessibility command line parameter).

I developed it in my spare time and for my personal use.

uiautomation is shared under the Apache Licence 2.0.
This means that the code can be freely copied and distributed, and costs nothing to use.

uiautomation1.x supports py2, py3 and doesn't depend on any third package.

uiautomation2.0+ only supports py3 and depends on comtypes and typing(Python3.5+ built-in).
uiautomation2.0+ is not backward compatible with early versions. See API changes.

You can install uiautomation by "pip install uiautomation". After installation, a automation.py that calls uiautomation will be in 'C:\PythonXX\Scripts'. You use this script to traverse UI controls.

Run 'C:\PythonXX\Scripts\automation.py -h' for help.
Run demos\automation_calculator.py to see a simple demo.

On Windows 8/8.1, to automate a Metro App, the app must be in foreground. If a Metro App was switched to background, uiautomation can't fetch its controls' information.

By the way, You should run python as administrator. Otherwise uiautomation may fail to enumerate controls or get controls' information on Windows 7 or higher.

Requirements:

Microsoft UIAutomation Minimum supported client: Windows 7, Windows Vista with SP2 and Platform Update for Windows Vista, Windows XP with SP3 and Platform Update for Windows Vista [desktop apps only]

Microsoft UIAutomation Minimum supported server: Windows Server 2008 R2, Windows Server 2008 with SP2 and Platform Update for Windows Server 2008, Windows Server 2003 with SP2 and Platform Update for Windows Server 2008 [desktop apps only]

C++ dll source code: UIAutomationClient


How to use uiautomation? run 'automation.py -h' help

Understand the arguments of automation.py, and try the following examples:
automation.py -t 0 -n, print current active window's controls, show fullname
automation.py -r -d 1 -t 0, print desktop(the root of control tree) and it's children(top level windows)

top level windows

automation.py prints the properties of controls and the patterns they support. You use controls and patterns to get controls' information and operate them.

A control should support some patterns or conditionally supports some patterns according to its control type.

patterns

Refer Control Pattern Mapping for UI Automation Clients for the full control pattern table.

uiautomation searches controls from the control tree based on the controls' properties you supply.

Suppose the control tree is

root(Name='Desktop', Depth=0)
  window1(Depth=1)
    control1-001(Depth=2)
    control1-...(Depth=2)
    ...
    control1-100(Depth=2)
  window2(Name='window2', Depth=1)
    control2-1(Depth=2)
      control2-1-001(Depth=3)
      control2-1-...(Depth=3)
      ...
      control2-1-100(Depth=3)
    control2-2(Depth=2)
    control2-3(Depth=2)
    control2-4(Name='2-4', Depth=2)
      editcontrol(Name='myedit1', Depth=3)
      editcontrol(Name='myedit2', Depth=3)

If you want to find the EditControl whose name is 'myedit2' and type 'hi',
you can write the following code:

uiautomation.EditControl(searchDepth=3, Name='myedit2').SendKeys('hi')

But this code run slowly because there are more than 200 controls before myedit2 in the control tree.
uiautomation has to traverse more than 200 controls before finding myedit2 if search from root in 3 search depth.
The better is:

window2 = uiautomation.WindowControl(searchDepth=1, Name='window2') # search 2 times
sub = window2.Control(searchDepth=1, Name='2-4')    # search 4 times
edit = sub.EditControl(searchDepth=1, Name='myedit2')   # search 2 times
edit.SendKeys('hi')

This code run faster than the former.
You can also combine the four lines code into one line.

uiautomation.WindowControl(searchDepth=1, Name='window2').Control(searchDepth=1, Name='2-4').EditControl(searchDepth=1, Name='myedit2').SendKeys('hi')

Now let's take notepad.exe for an example.
Luanch notepad.exe and run automation.py -t 3, then swith to Notepad and wait for 5 seconds

automation.py will print the controls of Notepad and save them to @AutomationLog.txt:

ControlType: PaneControl ClassName: #32769 Name: 桌面 Depth: 0 (Desktop window, the root control)
  ControlType: WindowControl ClassName: Notepad Depth: 1 (Top level window)
    ControlType: EditControl ClassName: Edit Depth: 2
      ControlType: ScrollBarControl ClassName: Depth: 3
        ControlType: ButtonControl ClassName: Depth: 4
        ControlType: ButtonControl ClassName: Depth: 4
      ControlType: ThumbControl ClassName: Depth: 3
    ControlType: TitleBarControl ClassName: Depth: 2
      ControlType: MenuBarControl ClassName: Depth: 3
        ControlType: MenuItemControl ClassName: Depth: 4
      ControlType: ButtonControl ClassName: Name: 最小化 Depth: 3 (Minimize Button)
      ControlType: ButtonControl ClassName: Name: 最大化 Depth: 3 (Maximize Button)
      ControlType: ButtonControl ClassName: Name: 关闭 Depth: 3 (Close Button)
...

Run the following code

# -*- coding: utf-8 -*-
import subprocess
import uiautomation as auto

print(auto.GetRootControl())
subprocess.Popen('notepad.exe')
# you should find the top level window first, then find children from the top level window
notepadWindow = auto.WindowControl(searchDepth=1, ClassName='Notepad')
if not notepadWindow.Exists(3, 1):
    print('Can not find Notepad window')
    exit(0)
print(notepadWindow)
notepadWindow.SetTopmost(True)
# find the first EditControl in notepadWindow
edit = notepadWindow.EditControl()
# use value pattern to get or set value
edit.GetValuePattern().SetValue('Hello')# or edit.GetPattern(auto.PatternId.ValuePattern)
edit.SendKeys('{Ctrl}{End}{Enter}World')
# find the first TitleBarControl in notepadWindow, 
# then find the second ButtonControl in TitleBarControl, which is the Maximize button
notepadWindow.TitleBarControl().ButtonControl(foundIndex=2).Click()
# find the first button in notepadWindow whose Name is '关闭', the close button
# the relative depth from Close button to Notepad window is 2
notepadWindow.ButtonControl(searchDepth=2, Name='关闭').Click()
# then notepad will popup a window askes you to save or not, press hotkey alt+n not to save
auto.SendKeys('{Alt}n')

auto.GetRootControl() returns the root control(the Desktop window)
auto.WindowControl(searchDepth=1, ClassName='Notepad') creates a WindowControl, the parameters specify how to search the control
the following parameters can be used
searchFromControl = None,
searchDepth = 0xFFFFFFFF,
searchInterval = SEARCH_INTERVAL,
foundIndex = 1
Name
SubName
RegexName
ClassName
AutomationId
ControlType
Depth
Compare

See Control.__init__ for the comments of the parameters.
See scripts in folder demos for more examples.

Control.Element returns the low level COM object IUIAutomationElement, Almost all methods and properties of Control are implemented via IUIAutomationElement COM API and Win32 API. when calling a control's method or property that indirectly calls Control.Element and Control.Element is None, uiautomation starts to search the control by the properties you supply. uiautomation will raise a LookupError exception if it can't find the control in uiautomation.TIME_OUT_SECOND(default 10 seconds). Control.Element will has a valid value if uiautomation finds the control successfully. You can use Control.Exists(maxSearchSeconds, searchIntervalSeconds) to check whether a control Exists, this function doesn't raise any exception. Call Control.Refind or Control.Exists to make Control.Element invalid again and uiautomation will starts a new search.

For example:

#!python3
# -*- coding:utf-8 -*-
import subprocess
import uiautomation as auto
auto.uiautomation.SetGlobalSearchTimeout(15)  # set new timeout 15


def main():
    subprocess.Popen('notepad.exe')
    window = auto.WindowControl(searchDepth=1, ClassName='Notepad')
    edit = window.EditControl()
    # when calling SendKeys, uiautomation starts to search window and edit in 15 seconds
    # because SendKeys indirectly calls Control.Element and Control.Element is None
    # if window and edit don't exist in 15 seconds, a LookupError exception will be raised
    try:
        edit.SendKeys('first notepad')
    except LookupError as ex:
        print("The first notepad doesn't exist in 15 seconds")
        return
    # the second call to SendKeys doesn't trigger a search, the previous call makes sure that Control.Element is valid
    edit.SendKeys('{Ctrl}a{Del}')
    window.GetWindowPattern().Close()  # close the first Notepad, window and edit become invalid even though their Elements have a value

    subprocess.Popen('notepad.exe')  # run second Notepad
    window.Refind()  # need to refind window, trigger a new search
    edit.Refind()  # need to refind edit, trigger a new search
    edit.SendKeys('second notepad')
    edit.SendKeys('{Ctrl}a{Del}')
    window.GetWindowPattern().Close()  # close the second Notepad, window and edit become invalid again

    subprocess.Popen('notepad.exe')  # run third Notepad
    if window.Exists(3, 1): # trigger a new search
        if edit.Exists(3):  # trigger a new search
            edit.SendKeys('third notepad')  # edit.Exists makes sure that edit.Element has a valid value now
            edit.SendKeys('{Ctrl}a{Del}')
        window.GetWindowPattern().Close()
    else:
        print("The third notepad doesn't exist in 3 seconds")


if __name__ == '__main__':
    main()

If automation.py can't print the controls you see. Maybe the controls were built by DirectUI(or CustomControl), not UI Frameworks supplied by Microsoft. In order to support UIAutomation, an UI Framework must implement UI Automation Provider.

A Microsoft UI Automation provider is a software object that exposes an element of an application's UI so that accessibility client applications can retrieve information about the element and invoke its functionality. In general, each control or other distinct element in a UI has a provider.

Microsoft includes a provider for each of the standard controls that are supplied with Microsoft Win32, Windows Forms, and Windows Presentation Foundation (WPF). This means that the standard controls are automatically exposed to UI Automation clients; you do not need to implement any accessibility interfaces for the standard controls.

If your application includes any custom controls, you need to implement UI Automation providers for those controls to make them accessible to accessibility client applications. You also need to implement providers for any third party controls that do not include a provider. You implement a provider by implementing UI Automation provider interfaces and control pattern interfaces.


Another UI tool Inspect.exe supplied by Microsoft can also be used to traverse the UI elements. It has an UI interface while my script shows UI elements in terminal. But I found that my script is more convenient sometimes.

Inspect


Some screenshots:

Batch rename pdf bookmark bookmark

Microsoft Word
Word

Wireshark 3.0 (Qt 5.12) Wireshark

GitHub Desktop (Electron App) GitHubDesktop

Pretty print dir
PrettyPrint

Owner
yin kaisheng
yin kaisheng
Scraping Bot for the Covid19 vaccination website of the Canton of Zurich, Switzerland.

Hi 👋 , I'm David A passionate developer from France. 🌱 I’m currently learning Kotlin, ReactJS and Kubernetes 👨‍💻 All of my projects are available

1 Nov 14, 2021
a plugin for py.test that changes the default look and feel of py.test (e.g. progressbar, show tests that fail instantly)

pytest-sugar pytest-sugar is a plugin for pytest that shows failures and errors instantly and shows a progress bar. Requirements You will need the fol

Teemu 963 Dec 28, 2022
Redis fixtures and fixture factories for Pytest.

Redis fixtures and fixture factories for Pytest.This is a pytest plugin, that enables you to test your code that relies on a running Redis database. It allows you to specify additional fixtures for R

Clearcode 86 Dec 23, 2022
A Python program that will log into your scheduled Google Meets hands free

Chrome GMautomation General Information This Python program will open up Chrome and log into your scheduled Google Meet with camera and mic turned off

Jonathan Leow 5 Dec 31, 2021
A simple serverless create api test repository. Please Ignore.

serverless-create-api-test A simple serverless create api test repository. Please Ignore. Things to remember: Setup workflow Change Name in workflow e

Sarvesh Bhatnagar 1 Jan 18, 2022
Repository for JIDA SNP Browser Web Application: Local Deployment

JIDA JIDA is a web application that retrieves SNP information for a genomic region of interest in Homo sapiens and calculates specific summary statist

3 Mar 03, 2022
A pytest plugin to skip `@pytest.mark.slow` tests by default.

pytest-skip-slow A pytest plugin to skip @pytest.mark.slow tests by default. Include the slow tests with --slow. Installation $ pip install pytest-ski

Brian Okken 19 Jan 04, 2023
Show surprise when tests are passing

pytest-pikachu pytest-pikachu prints ascii art of Surprised Pikachu when all tests pass. Installation $ pip install pytest-pikachu Usage Pass the --p

Charlie Hornsby 13 Apr 15, 2022
API Rest testing FastAPI + SQLAchmey + Docker

Transactions API Rest Implement and design a simple REST API Description We need to a simple API that allow us to register users' transactions and hav

TxeMac 2 Jun 30, 2022
Based on the selenium automatic test framework of python, the program crawls the score information of the educational administration system of a unive

whpu_spider 该程序基于python的selenium自动化测试框架,对某高校的教务系统的成绩信息实时爬取,在检测到成绩更新之后,会通过电子邮件的方式,将更新的成绩以文本的方式发送给用户,可以使得用户在不必手动登录教务系统网站时,实时获取成绩更新的信息。 该程序仅供学习交流,不可用于恶意攻

1 Dec 30, 2021
Divide full port scan results and use it for targeted Nmap runs

Divide Et Impera And Scan (and also merge the scan results) DivideAndScan is used to efficiently automate port scanning routine by splitting it into 3

snovvcrash 226 Dec 30, 2022
Front End Test Automation with Pytest Framework

Front End Test Automation Framework with Pytest Installation and running instructions: 1. To install the framework on your local machine: clone the re

Sergey Kolokolov 2 Jun 17, 2022
Automação de Processos (obtenção de informações com o Selenium), atualização de Planilha e Envio de E-mail.

Automação de Processo: Código para acompanhar o valor de algumas ações na B3. O código entra no Google Drive, puxa os valores das ações (pré estabelec

Hemili Beatriz 1 Jan 08, 2022
A simple script to login into twitter using Selenium in python.

Quick Talk A simple script to login into twitter using Selenium in python. I was looking for a way to login into twitter using Selenium in python. Sin

Lzy-slh 4 Nov 20, 2022
This project demonstrates selenium's ability to extract files from a website.

This project demonstrates selenium's ability to extract files from a website. I've added the challenge of connecting over TOR. This package also includes a personal archive site built in NodeJS and A

2 Jan 16, 2022
A command-line tool and Python library and Pytest plugin for automated testing of RESTful APIs, with a simple, concise and flexible YAML-based syntax

1.0 Release See here for details about breaking changes with the upcoming 1.0 release: https://github.com/taverntesting/tavern/issues/495 Easier API t

909 Dec 15, 2022
Penetration testing

Penetration testing

3 Jan 11, 2022
Let your Python tests travel through time

FreezeGun: Let your Python tests travel through time FreezeGun is a library that allows your Python tests to travel through time by mocking the dateti

Steve Pulec 3.5k Dec 29, 2022
CNE-OVS-SIT - OVS System Integration Test Suite

CNE-OVS-SIT - OVS System Integration Test Suite Introduction User guide Discussion Introduction CNE-OVS-SIT is a test suite for OVS end-to-end functio

4 Jan 09, 2022
Django test runner using nose

django-nose django-nose provides all the goodness of nose in your Django tests, like: Testing just your apps by default, not all the standard ones tha

Jazzband 880 Dec 15, 2022