Proyek
Aether
Aether is a lightweight, high-performance, and safety-focused Windows automation utility and workflow runner. Built in C#/.NET 8 and WPF with direct Win32 SendInput injection, it guarantees input release safety, target window focus gating, and coordinate-relative positioning.
C#.NET 8WPFWin32 APIWindows
Overview
Aether 🖱️
Aether is a native Windows workflow automation utility built for users who want:
- Guaranteed Input Cleanup: Ensures simulated mouse buttons and modifier keys are released on cancel, crash, or forced-exit.
- Target Window Gating: Automatically pauses automation when the target window loses focus and resumes upon focus recovery.
- Precise Timing Control: Uses high-resolution multimedia timers for sub-millisecond precision with minimal CPU overhead.
- Advanced Workflow Authoring: Supports multi-step sequences with custom delays, nested loop blocks, and coordinate offsets.
- Low-Latency Simulation: Simulates user inputs atomically via Win32
SendInputwithout kernel-level drivers. - Relative Coordinates: Target points can be defined relative to the screen, window, or client area to survive moved or resized windows.
Key Features
- High-Resolution Timer Loop: Compensates for timer drift using system multimedia timers, maintaining ticks within 5ms under load.
- Global Hotkey Controller: Integrates Win32
RegisterHotKeyto toggle the armed state with an automatic suggestion engine for key conflicts. - Safety-Critical Releases: Listens to system/process exit events and cancellation tokens to execute
EnsureReleaseAll()unconditionally. - Expanded Action Types: Supports scrolls, keyboard keypresses, mouse button holds, and modifier combinations.
- Workflow Editing & UX: Enables step duplication, drag-and-drop step reordering, inline parameter validation, and running custom subsets.
- Randomization Options: Emulates human interactions by adding randomized min/max jitter ranges and fixed-position pixel variance.
Tech Stack
- UI Shell: WPF (.NET 8) with custom styled MVVM components.
- Core Engine: C# (.NET 8) state machine-driven scheduler.
- Native Interop: Direct P/Invoke bindings for Win32 User32 and Winmm libraries.
- Persistence: JSON-based local profiles and configurations stored in
%APPDATA%\Aether.
Architecture
Aether is designed around a strictly decoupled, interface-driven architecture that enforces the Dependency Inversion Principle (DIP). The core scheduling and state machine components have zero dependencies on direct Windows APIs or presentation framework libraries, enabling fully deterministic unit-testing via mock abstractions.
Layered Topology & Control Flow
The application is structured into three clean layers:
┌──────────────────────────────────────────────────────────────────┐
│ PRESENTATION │
│ [Aether.App] │
│ │
│ ┌─────────────────┐ ┌─────────────────────┐ │
│ │ MainWindow (UI) │◄──────────────►│ GlobalHotkeyService │ │
│ └────────┬────────┘ └──────────┬──────────┘ │
└─────────────┼────────────────────────────────────┼───────────────┘
│ Commands & Updates │ Events (WM_HOTKEY)
▼ ▼
┌─────────────┼────────────────────────────────────┼───────────────┐
│ ▼ │ │
│ ┌──────────────────────────────────┐ │ │
│ │ AutomationController │◄─────────┘ │
│ │ (State Machine) │ │
│ └────────────────┬─────────────────┘ │
│ │ Starts/Cancels │
│ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ SchedulerEngine │ CORE DOMAIN │
│ │ (High-Res Timing Loop) │ [Aether.Core] │
│ └────────┬────────────────┬────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │IInputInjector│ │ ITargetGuard │ (Interfaces / Boundary) │
│ └───────▲──────┘ └──────▲───────┘ │
└─────────────┼────────────────┼───────────────────────────────────┘
│ Implements │ Implements
┌─────────────┼────────────────┼───────────────────────────────────┐
│ │ │ │
│ ┌───────┴──────┐ ┌──────┴───────┐ │
│ │SendInputInj. │ │TargetWindowG.│ INFRASTRUCTURE │
│ └───────┬──────┘ └──────┬───────┘ [Aether.Infrastructure] │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────────────────────────┐ │
│ │ Win32 Subsystem │ │
│ │ (SendInput / GetForegroundWnd) │ │
│ └────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
Key Architectural Patterns
- Dependency Inversion: Core components (like the
SchedulerEngine) consume abstractions (IInputInjector,ITargetWindowGuard). Concrete classes wrapping P/Invoke structures live solely inside theInfrastructuretier. - Process & Safety Guarantees: A global
RuntimeSafetyGuardtracks simulated held buttons and modifier keys. Under cancellation or unexpected process termination, a fail-safe cleanup routine triggers to prevent stuck inputs:
public void EnsureReleaseAll()
{
EnsureRelease(MouseButton.Left);
EnsureRelease(MouseButton.Right);
EnsureRelease(MouseButton.Middle);
int[] keysToRelease;
HotkeyModifiers[] modifiersToRelease;
lock (_sync)
{
keysToRelease = _heldKeys.ToArray();
modifiersToRelease = _heldModifiers.ToArray();
}
foreach (var key in keysToRelease)
{
SendKeyboardInput((ushort)key, NativeMethods.KeyeventfKeyup);
}
foreach (var modifier in modifiersToRelease)
{
var vk = GetVirtualKeyForModifier(modifier);
SendKeyboardInput(vk, NativeMethods.KeyeventfKeyup);
}
}