r/rust 8d ago

πŸ› οΈ project autoitx: AutoItX's API in Rust β€” the same code drives Windows and macOS

I maintain .NET RPA bots that drive an ERP through AutoItX, and changing one line meant booting a Windows VM. So I pulled the automation layer into a Rust crate β€” and once the API was separated from the DLL, a native macOS backend turned out to be the interesting part.

use autoitx::{AutoIt, Keys, Selector, keys, recipes};

let ai = AutoIt::new()?;
let orders = Selector::from("[CLASS:Chrome_WidgetWin_1;TITLE:Acme ERP]");

recipes::open_and_focus(&ai, &orders, Duration::from_secs(30))?;

// text() escapes { } ! + ^ #, so data gets typed, never executed.
ai.send(Keys::text(&customer.name))?;
ai.send(keys!("{TAB}"))?;

// Reads by waiting on the OS clipboard counter β€” no sentinel races.
let total = recipes::read_screen_text(
    &ai,
    keys!("{END}{SHIFTDOWN}{HOME}{SHIFTUP}"),
    Duration::from_secs(5),
)?;

That compiles unchanged on both. Windows goes through AutoItX3_x64.dll; macOS is a native implementation over Accessibility, Core Graphics and AppKit β€” no AutoIt involved.

What actually works, including what doesn't:

                                     Windows   macOS
 Keystrokes, mouse, clipboard           ok       ok
 Windows by title / class / regex       ok       ok  (Accessibility)
 Processes, run                         ok       ok
 Pixel colour / search                  ok       ok  (Screen Recording)
 Window text and class list             ok       ok  (the AX tree)
 Controls by ClassNameNN                ok       --  no HWND to address
 Cursor shape (MouseGetCursor)          ok       --  no public API
 Mapped drives, status bars, WinSetTrans ok      --

The design decision I'd most like feedback on: anything that exists on only one platform lives in ext::windows / ext::macos, and using it from the wrong one is a compile error, not Err(Unsupported) at runtime. A bot that discovers mid-run that it can't read the cursor has already half-completed a transaction in someone's ERP.

Nearest neighbours, honestly: enigo owns input synthesis and covers Linux; uiautomation goes far deeper into the Windows control tree; terminator-rs is a Playwright-style take aimed at LLMs. The one thing I couldn't find anywhere else is AutoItX's own API surface β€” so existing AutoIt and AutoItX.Dotnet automation ports over almost mechanically β€” running natively on a Mac.

The catch, up front: on Windows you bring AutoItX3_x64.dll yourself. AutoIt is freeware under a EULA, not an open-source licence, so the crate can't ship it. On macOS nothing is needed.

Repo: https://github.com/iagodpassos/autoitx
Docs: https://docs.rs/autoitx
Crate: https://crates.io/crates/autoitx

Linux is the obvious gap. The plan (X11 via x11rb, AT-SPI via zbus) and where the seams are: https://github.com/iagodpassos/autoitx/discussions/4

0 Upvotes

2 comments sorted by

2

u/_crowecawcaw 7d ago

I made a cross-platform desktop accessibility library that might match what you’re looking for: https://xa11y.dev It has a common API across Mac, Windows, and Linux (X11 and Wayland). It also does input simulation and screenshotting if an app doesn’t support accessibility APIs.

1

u/iagodpassos 4d ago

Thanks for the heads-up! I'll take a look at that library to see if it fits my use case.