20 releases

Uses new Rust 2021

0.1.10 Aug 3, 2022
0.1.9 Jun 30, 2022
0.1.1 May 21, 2022
0.0.9 May 6, 2022
0.0.2 Mar 3, 2022

#20 in Windows APIs

Download history 29/week @ 2022-04-24 79/week @ 2022-05-01 66/week @ 2022-05-08 195/week @ 2022-05-15 62/week @ 2022-05-22 105/week @ 2022-05-29 125/week @ 2022-06-05 32/week @ 2022-06-12 25/week @ 2022-06-19 99/week @ 2022-06-26 15/week @ 2022-07-03 28/week @ 2022-07-10 42/week @ 2022-07-17 57/week @ 2022-07-24 70/week @ 2022-07-31 15/week @ 2022-08-07

186 downloads per month

Apache-2.0

290KB
7.5K SLoC

Rust for windows uiautomation

The uiatomation-rs crate is a wrapper for windows uiautomation. This crate can help you make windows uiautoamtion API calls conveniently.

Usages

Start by adding the following line to your Cargo.toml file:

[dependencies]
uiautomation = "0.1.10"

Make use of any windows uiautomation calls as needed.

Examples

Print All UIElements

use uiautomation::Result;
use uiautomation::UIAutomation;
use uiautomation::UIElement;
use uiautomation::UITreeWalker;

fn main() {
    let automation = UIAutomation::new().unwrap();
    let walker = automation.get_control_view_walker().unwrap();
    let root = automation.get_root_element().unwrap();

    print_element(&walker, &root, 0).unwrap();
}

fn print_element(walker: &UITreeWalker, element: &UIElement, level: usize) -> Result<()> {
    for _ in 0..level {
        print!(" ")
    }
    println!("{} - {}", element.get_classname()?, element.get_name()?);

    if let Ok(child) = walker.get_first_child(&element) {
        print_element(walker, &child, level + 1)?;

        let mut next = child;
        while let Ok(sibing) = walker.get_next_sibling(&next) {
            print_element(walker, &sibing, level + 1)?;

            next = sibing;
        }
    }
    
    Ok(())
}

Open Notepad and Input Text

use uiautomation::core::UIAutomation;
use uiautomation::processes::Process;

fn main() {
    Process::create("notepad.exe").unwrap();

    let automation = UIAutomation::new().unwrap();
    let root = automation.get_root_element().unwrap();
    let matcher = automation.create_matcher().from(root).timeout(10000).classname("Notepad");
    if let Ok(notepad) = matcher.find_first() {
        println!("Found: {} - {}", notepad.get_name().unwrap(), notepad.get_classname().unwrap());

        notepad.send_keys("Hello,Rust UIAutomation!{enter}", 10).unwrap();

        let window: WindowControl = notepad.try_into().unwrap();
        window.maximize().unwrap();
    }
}

Get Properties As Variant

use uiautomation::UIAutomation;
use uiautomation::variants::Variant;
use windows::Win32::UI::Accessibility::UIA_ControlTypePropertyId;
use windows::Win32::UI::Accessibility::UIA_IsEnabledPropertyId;
use windows::Win32::UI::Accessibility::UIA_NamePropertyId;

fn main() {
    let automation = UIAutomation::new().unwrap();
    let root = automation.get_root_element().unwrap();

    let name: Variant = root.get_property_value(UIA_NamePropertyId).unwrap();
    println!("name = {}", name.get_string().unwrap());

    let ctrl_type: Variant = root.get_property_value(UIA_ControlTypePropertyId).unwrap();
    let ctrl_type_id: i32 = ctrl_type.try_into().unwrap();
    println!("control type = {}", ctrl_type_id);

    let enabled: Variant = root.get_property_value(UIA_IsEnabledPropertyId).unwrap();
    let enabled_str: String = enabled.try_into().unwrap();
    println!("enabled = {}", enabled_str);
}

Simulate Keyboard Input

use uiautomation::core::UIAutomation;

fn main() {
    let automation = UIAutomation::new().unwrap();
    let root = automation.get_root_element().unwrap();
    root.send_keys("{Win}D", 10).unwrap();
}

Dependencies

~199MB
~3.5M SLoC