Community contribution · Forked from Verisoft-ai/appium-wincore-driver
A drop-in Appium 2/3 driver for Windows that tackles the limitations of WinAppDriver — faster XPath, layout-safe input, and no extra setup required.
npm install -g appium
appium driver install --source=npm appium-wincore-driver
See it in action
Watch the driver automate a real Windows application end-to-end — element finding, input simulation, and test execution.
Why switch
WinAppDriver is abandoned and ships known pain points. Here's what this driver does instead.
| Problem with WinAppDriver | What this driver does instead |
|---|---|
| ✗Slow XPath on complex UIs | ✓Faster XPath via direct UIA3 tree traversal |
| ✗Can't access hidden/raw elements | ✓RawView element support |
| ✗Keyboard layout–dependent input | ✓Unicode-safe text input with layout bypass |
| ✗Requires Developer Mode or extra setup | ✓Zero extra prerequisites — PowerShell only |
| ✗No MCP / AI agent support | ✓Built-in MCP server with 30+ tools |
Compatibility
Works with every Windows application framework — including legacy apps with sparse accessibility trees.
What you get
Everything you need for production-grade Windows UI automation.
Drop-in driver for the modern Appium stack. Familiar W3C WebDriver protocol — works with any Appium client.
Element lookups via Windows UI Automation 3 (UIA3). XPath evaluated against the live UIA tree with RawView access for hidden elements.
Mouse (click, scroll, hover, drag, Bezier easing), keyboard (unicode, virtual key codes, modifier combos), and clipboard. All via native user32.dll calls.
30+ executeScript commands: invoke/expand/collapse/toggle UI patterns, set/get values, manage windows, control monitors, run PowerShell, record screen.
An out-of-the-box Model Context Protocol server (desktop-driver-mcp) exposes 30+ tools so AI agents can automate Windows UIs without writing traditional test scripts.
Run arbitrary PowerShell before/after sessions (prerun/postrun), inject environment variables, and execute raw scripts mid-test.
Element finding
All supported locators with their UIA mapping and an example selector.
| Strategy | Maps to | Example |
|---|---|---|
accessibility id |
UIA AutomationId | AppNameTitle |
name |
UIA Name | Calculator |
class name |
UIA ClassName | TextBlock |
tag name |
UIA ControlType | Button |
xpath |
Live UIA tree XPath 1.0 | //Button[@Name="OK"] |
id |
Alias for accessibility id | 42.333896.3.1 |
-windows uiautomation |
Raw UIA condition (C#/PS syntax) | new PropertyCondition(...) |
AI agent integration
Connect Claude, Copilot, or any MCP-compatible AI agent to any Windows app in minutes.
desktop-driver-mcpStart your Appium server, then run desktop-driver-mcp to connect and create a session.
Point Claude Desktop, Cursor, or any MCP-compatible client to the server via stdio transport.
The agent finds elements, clicks, types, takes screenshots, and reads the UI tree — all without you writing test code.
{
"mcpServers": {
"windows": {
"command": "desktop-driver-mcp",
"args": [],
"env": {
"APP": "C:\\Windows\\System32\\notepad.exe"
}
}
}
}
| Group | Tools | Description |
|---|---|---|
| Session | start_session, get_session_info, end_session |
Lifecycle management |
| Find | find_element, find_elements, find_child_element, wait_for_element |
Element discovery with selector guidance |
| Inspect | get_element_info |
Reads UIA properties and returns ranked selector suggestions |
| Interact | click_element, set_value, clear_element, get_text, get_attribute, is_element_displayed, is_element_enabled |
Basic interactions |
| Advanced | advanced_click, send_keys, hover, scroll, click_and_drag |
Complex input (right-click, double-click, drag, modifier keys) |
| Window | take_screenshot, get_page_source, get_window_rect, get_window_handles, switch_to_window, maximize_window, minimize_window, restore_window, close_window, get_monitors |
Window & screen control |
| UI Patterns | invoke, expand_element, collapse_element, toggle_element, scroll_into_view, select_element, get_selected_item, get_all_selected_items, add_to_selection, remove_from_selection, get_element_value, set_element_value, is_multiple_selection |
UIA interaction patterns |
| App | get_window_element, launch_app, close_app, get_device_time |
App lifecycle |
| Clipboard | set_clipboard, get_clipboard |
Clipboard read/write (text and images) |
Get started fast
Connect to any Windows app in under 10 lines.
from appium import webdriver
from appium.options.windows import WindowsOptions
options = WindowsOptions()
options.app = 'C:\\Windows\\System32\\notepad.exe'
options.automation_name = 'Wincore'
driver = webdriver.Remote('http://127.0.0.1:4723', options=options)
# Find and interact
title_bar = driver.find_element('name', 'Notepad')
driver.execute_script('windows: maximize', title_bar)
import io.appium.java_client.windows.WindowsDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.net.URL;
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("platformName", "Windows");
caps.setCapability("appium:automationName", "Wincore");
caps.setCapability("appium:app", "C:\\Windows\\System32\\notepad.exe");
WindowsDriver driver = new WindowsDriver(
new URL("http://127.0.0.1:4723"),
caps
);
driver.findElementByName("Notepad").click();
import { remote } from 'webdriverio';
const driver = await remote({
hostname: '127.0.0.1',
port: 4723,
capabilities: {
platformName: 'Windows',
'appium:automationName': 'Wincore',
'appium:app': 'C:\\Windows\\System32\\notepad.exe',
},
});
const el = await driver.$('~AppNameTitle');
await el.click();
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Windows;
var options = new AppiumOptions();
options.PlatformName = "Windows";
options.AddAdditionalAppiumOption("automationName", "Wincore");
options.AddAdditionalAppiumOption("app", @"C:\Windows\System32\notepad.exe");
var driver = new WindowsDriver(
new Uri("http://127.0.0.1:4723"),
options
);
driver.FindElement(MobileBy.AccessibilityId("AppNameTitle")).Click();
options.smooth_pointer_move = 'ease-in-out'
options.delay_before_click = 100 # ms
options.app_top_level_window = 0x12345 # attach to existing window
options.prerun = {'script': 'Start-Process notepad'}
options.postrun = {'command': 'Stop-Process -Name notepad'}
options.app_environment = {'MY_VAR': 'hello'}
options.return_all_window_handles = True
Configuration
All supported capabilities and their defaults.
| Capability | Type | Default | Description |
|---|---|---|---|
platformName | string | — | Must be Windows |
automationName | string | — | Must be Wincore |
app | string | — | App path or UWP App User Model ID |
appTopLevelWindow | string/number | — | Attach to existing window by handle |
appArguments | string | — | CLI arguments for app launch |
appWorkingDir | string | — | Working directory for app |
smoothPointerMove | string | — | CSS easing for mouse movement (e.g. ease-in) |
delayBeforeClick | number | — | ms delay before each click |
delayAfterClick | number | — | ms delay after each click |
shouldCloseApp | boolean | true | Close app window when session ends |
prerun | object | — | {script: '...'} or {command: '...'} to run before session |
postrun | object | — | Same as prerun, runs after session |
isolatedScriptExecution | boolean | false | Run PowerShell scripts in isolated scope |
appEnvironment | object | — | Custom env vars injected into PS session |
ms:waitForAppLaunch | number | 0 | Seconds to wait for app window after launch |
Platform commands
executeScript ExtensionsAll windows: commands grouped by category.
windows: click — advanced click with modifier keys, multi-click, durationwindows: scroll — mouse wheel (horizontal or vertical)windows: hover — mouse move from A to Bwindows: keys — keyboard input (text, virtual key codes, modifiers)windows: clickAndDrag — click-press-move-release dragwindows: invoke, windows: expand, windows: collapsewindows: toggle, windows: setValue, windows: getValuewindows: select, windows: addToSelection, windows: removeFromSelectionwindows: selectedItem, windows: allSelectedItems, windows: isMultiplewindows: scrollIntoView, windows: setFocuswindows: maximize, windows: minimize, windows: restore, windows: closewindows: getMonitors — multi-monitor infowindows: getWindowElement — root element of current windowwindows: launchApp, windows: closeAppwindows: setClipboard, windows: getClipboardwindows: startRecordingScreen, windows: stopRecordingScreenwindows: deleteFile, windows: deleteFolderwindows: pushCacheRequest — UIA RawView element caching