Token导航 LogoToken导航TokenDH.com
winjavadriver logo
运维云端未说明官方级别未说明来源级核验

winjavadriver

MCP Server

WinJavaDriver是一个实现W3C WebDriver协议的Windows桌面自动化工具,支持通过Java使用类似Selenium的API自动化Windows应用程序。

工具数

24

提示词数

0

GitHub Stars

10

资源数

0
Java云端部署Docker

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

glaciousm

提供方

glaciousm

最后核验

2026/5/17 20:21

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

WinJava驱动程序

![CI](https://github.com/glaciousm/winjavadriver/actions/workflows/ci.yml)

一个实现W3C WebDriver协议的Windows桌面自动化工具。使用熟悉的Selenium风格的API(类似ChromeDriver)从Java自动化Windows应用程序,但适用于Windows桌面应用程序。

特性

  • W3C WebDriver协议 --基于HTTP的标准自动化接口
  • Java客户端库 --扩展硒的 RemoteWebDriver 实现完全的生态系统兼容性
  • Windows用户界面自动化 --将Microsoft的UIAutomation框架用于现代应用程序
  • 旧版Win32/VB6支持 --UIA不可见的应用程序的自动回退
  • 专注独立互动 --单击、键入和截图,而无需将窗口放在前面
  • W3C操作API --通过Selenium的双击、右键单击、拖放、悬停和键盘快捷键 Actions
  • MSFlexGrid单元自动化 --读取和写入VB6 MSFlexGrid控件中的单个单元格
  • 检查器GUI --Chrome DevTools风格的元素间谍,具有悬停高亮显示、多定位器面板和VB6标签支持
  • 录制与回放 --记录用户交互,生成Java页面对象或JUnit测试代码,回放步骤
  • MCP服务器 --AI驱动的桌面自动化,配备智能、令牌高效的工具
  • 多种定位策略 --名称、可访问性ID、类名、标记名、xpath
  • 名称规范化WinBy.name("Open") 自动匹配两者 "Open""&Open" (Windows快捷键前缀)
  • 窗户链条switchTo().window(handle) 跟踪前一个窗口, switchBack() 返回到它
  • 系统窗口发现listAllWindows() 枚举所有可见窗口; switchToWindowByTitle() 按标题片段切换
  • 便利API --等待助手、元素索引、子枚举、基于位置的查找、重试和全局 sendKeys()
  • 截图 --窗口、元素和完整桌面屏幕截图捕获(与z顺序无关)
  • Selenium Grid 4集成 --通过网格中继在远程Windows计算机上运行测试
  • 黄瓜/BDD就绪 --计算器自动化示例项目

快速开始

先决条件

  • Windows 10/11
  • Java 21+(客户端)

安装

  1. 将Java客户端添加到您的项目中——服务器二进制文件是 自动下载 首次运行时:

    io.github.glaciousm
    winjavadriver-client
    1.1.0

基本用法

import io.github.glaciousm.*;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.OutputType;

public class NotepadAutomation {
    public static void main(String[] args) {
        // Create options to launch Notepad
        WinJavaOptions options = new WinJavaOptions()
            .setApp("notepad.exe");

        // Start driver — auto-discovers winjavadriver.exe, auto-starts server
        // (identical to how ChromeDriver works)
        WinJavaDriver driver = new WinJavaDriver(options);

        try {
            // Standard Selenium API — returns WebElement, not a custom type
            WebElement editArea = driver.findElement(WinBy.className("RichEditD2DPT"));
            editArea.sendKeys("Hello from WinJavaDriver!");

            // Selenium-standard screenshot
            driver.getScreenshotAs(OutputType.FILE);

        } finally {
            // Close the session and stop the server
            driver.quit();
        }
    }
}

定位器策略

策略描述示例
WinBy.name(value)元素的Name属性WinBy.name("Save")
WinBy.accessibilityId(value)Automation Id(最可靠)WinBy.accessibilityId("btnSave")
WinBy.className(value)Win32类名WinBy.className("Edit")
By.tagName(value)控制类型By.tagName("button")
By.xpath(expression)XPath over UI树By.xpath("//Button[@Name='Save']")

名称规范化

Windows控件通常包括加速器键前缀(例如。, "&Open" 用于Alt+O快捷键)。WinJavaDriver会自动规范名称,以便 WinBy.name("Open") 匹配两者 "Open""&Open"。无需配置。

发现元素定位器

GUI检查器(推荐)

启动独立的检查器工具:

winjavadriver-inspector.exe

特征:

  • 深色主题 (材质设计)采用Chrome DevTools风格布局
  • 悬停高亮显示 --将鼠标悬停在元素上以查看其类型、名称和大小
  • 单击以捕获 --单击任何元素(或Ctrl+Q)将其选中
  • 多定位器面板 --使用复制按钮查看所有定位器策略(accessibilityId、name、className、xpath)
  • Java代码面板 --准备粘贴Selenium/WinJavaDriver代码片段
  • 定位器控制台 --根据实时UI树测试定位器
  • VB6标签支持 --发现无窗口的VB6标签控件
  • 面包屑导航 --单击路径段以浏览元素树
  • DPI感知 --在高DPI显示器上正常工作

CLI检查模式(传统)

winjavadriver.exe --inspect

录制与回放

Inspector包括一个内置的记录器,可以捕获用户交互并生成可执行的测试代码。

录制

  1. 打开检查器并单击 记录
  2. 检查器最小化并显示浮动记录工具栏(始终位于顶部,可拖动)
  3. 与应用程序正常交互——点击、打字和键盘快捷键都是被动捕获的
  4. 停止 在工具栏(或ESC)上完成录制

记录的内容:

  • 点击 --单击、双击、右键单击元素标识
  • 文本输入 --按键被缓冲并合并到SendKeys操作中(5秒刷新)
  • 键盘快捷键 --Ctrl+S、Alt+F4、Ctrl+Shift+N等,带有修饰符跟踪功能
  • 导航键 --箭头键、Tab键、Enter键、向上/向下翻页、主页、结束、退格、删除
  • 截图 --每一步都会捕获一个元素截图以供视觉参考

附加功能:

  • 暂停/恢复 --暂时暂停录制而不停止
  • 可编辑文本框 --展开步骤以编辑记录的文本或预期值
  • 添加评论 --用用户注释注释步骤
  • 添加断言 --Ctrl+Shift+Click将元素名称捕获为断言
  • 步骤管理 --重新排序、删除或修改记录的步骤
  • 自我过滤 --在检查器或工具栏上的点击不会被记录

代码生成

录制后,单击 生成代码 生产:

  • Java页面对象 --类与 By 定位器字段、构造函数和 performActions() 方法
  • JUnit5测试 --独立测试类 @BeforeEach/@AfterEach 生命周期, @Test 方法

生成的代码特征:

  • WebDriverWait.until() 用于可靠的元素查找(默认超时10秒)
  • 通过基于标题的匹配进行窗口切换 getWindowHandles()
  • Actions 用于右键单击的类(contextClick)然后双击(doubleClick)
  • Keys.chord() 用于快捷键(Ctrl+S、Alt+F4等)
  • 导航键映射到Selenium Keys 常量
  • assertEquals() 用于断言步骤
  • 当不存在稳定标识符时,基于位置的元素过滤(±20px容差)
  • 用户注释保留为Java代码注释

回放

点击 回放 针对实时应用程序重新执行记录的步骤:

  • 按Automation Id(首选)或Name+ClassName重新查找元素
  • 通过标题匹配处理窗口切换
  • 支持所有操作类型(单击、类型、快捷方式、断言)
  • 退出 随时取消重播

API 参考

WinJavaDriver(扩展了Selenium的RemoteWebDriver)

import io.github.glaciousm.*;
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.*;

// Auto-discover exe, auto-start server (like ChromeDriver)
WinJavaDriver driver = new WinJavaDriver(options);

// Or connect to an already-running server
WinJavaDriver driver = new WinJavaDriver(new URL("http://localhost:9515"), options);

// Standard Selenium API — returns WebElement
WebElement element = driver.findElement(WinBy.name("Save"));
List elements = driver.findElements(By.tagName("button"));

// Screenshots
File screenshot = driver.getScreenshotAs(OutputType.FILE);      // app window
File desktopShot = driver.getDesktopScreenshot(OutputType.FILE); // entire screen

// Page source, timeouts, cleanup
String xml = driver.getPageSource();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
driver.quit();

等待助手

方法说明
waitForElement(By locator)等待元素存在于UI树中(默认10秒)
waitForElement(By locator, Duration timeout)使用自定义超时等待
waitForClickable(By locator)等待元素可见并启用(默认10秒)
waitForClickable(By locator, Duration timeout)等待可点击的自定义超时
waitForWindowCount(int count)等待N个窗口打开(默认10秒),返回句柄
waitForWindowCount(int count, Duration timeout)使用自定义超时等待窗口计数
WebElement el = driver.waitForElement(WinBy.name("Ready"));
WebElement btn = driver.waitForClickable(WinBy.name("Save"), Duration.ofSeconds(5));
Set handles = driver.waitForWindowCount(2);

窗口管理

方法说明
switchBack()切换到上次之前打开的窗口 switchTo().window() 呼叫
switchToWindowByTitle(String titleFragment)按标题查找并切换到系统上的任何窗口(区分大小写包含匹配项)
listAllWindows()列出系统上所有可见的窗口--返回 List 随着 handle, title, className, processId
// Switch to popup, interact, switch back — no need to store the main handle
driver.switchTo().window(popupHandle).findElement(WinBy.name("OK")).click();
driver.switchBack();

// Find and switch to a child window from a different process
driver.switchToWindowByTitle("POS_PREPROD");

// Discover all windows (useful when getWindowHandles() doesn't return child windows)
List> windows = driver.listAllWindows();
windows.forEach(w -> System.out.println(w.get("title") + " → " + w.get("handle")));

元素查找助手

方法说明
findElementByIndex(By locator, int index)找到与定位器匹配的第N个元素(从0开始)。适用于没有唯一名称的VB6控件。
findElementByPosition(By locator, int row, int col)通过视觉网格位置查找元素。按Y坐标(±20px)对元素进行分组,每行按X排序。
findElementByPosition(By locator, int row, int col, int tolerance)与自定义Y公差相同(默认为20px,高DPI时增加)。
findChildren(WebElement parent)获取一个元素的所有直接子元素。适用于UIA和Win32/VB6(MSAA)。
findChildren(WebElement parent, int index)获取第N个直接子项(从0开始)。
// VB6 form with 10 identical TextBox controls — get the 3rd one
WebElement field = driver.findElementByIndex(WinBy.className("ThunderRT6TextBox"), 2);

// Grid-like layout — find element at row 1, column 3
WebElement cell = driver.findElementByPosition(WinBy.className("ThunderRT6TextBox"), 1, 3);

// Enumerate children of a container
List children = driver.findChildren(panel);
WebElement firstChild = driver.findChildren(panel, 0);

输入并重试

方法说明
sendKeys(CharSequence... keys)将密钥发送到活动/聚焦元素,而不需要元素引用。
retry(Runnable action, int maxAttempts, Duration delay)最多重试N次操作,两次尝试之间有延迟。毕竟投掷失败了。
// Keyboard shortcuts without finding an element first
driver.sendKeys(Keys.chord(Keys.CONTROL, "o")); // Ctrl+O
driver.sendKeys(Keys.ENTER);

// Retry a flaky VB6 click
driver.retry(() -> driver.findElement(WinBy.name("Save")).click(), 3, Duration.ofMillis(500));

WebElement(标准硒)

// Interactions
element.click();
element.clear();
element.sendKeys("text to type");

// Properties
String text = element.getText();
String tagName = element.getTagName();
boolean enabled = element.isEnabled();
boolean displayed = element.isDisplayed();
String attr = element.getAttribute("ClassName");
Rectangle rect = element.getRect();

// Find child elements
WebElement child = element.findElement(WinBy.name("Child"));
List children = element.findElements(By.tagName("listitem"));

W3C操作API

Actions 类完全支持复杂的交互:

import org.openqa.selenium.interactions.Actions;

Actions actions = new Actions(driver);

// Right-click (context menu)
actions.contextClick(element).perform();

// Double-click
actions.doubleClick(element).perform();

// Hover over element
actions.moveToElement(element).perform();

// Drag and drop
actions.dragAndDrop(source, target).perform();

// Keyboard shortcut (Ctrl+S)
actions.keyDown(Keys.CONTROL).sendKeys("s").keyUp(Keys.CONTROL).perform();

// Ctrl+Click
actions.keyDown(Keys.CONTROL).click(element).keyUp(Keys.CONTROL).perform();

// Key combos with modifier tracking (proper release order)
actions.keyDown(Keys.SHIFT).sendKeys(Keys.F10).keyUp(Keys.SHIFT).perform();

显式等待(硒标准)

import org.openqa.selenium.support.ui.*;

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

// Wait for element to be present in the UI tree
WebElement element = wait.until(
    ExpectedConditions.presenceOfElementLocated(WinBy.name("Ready")));

// Wait for element to be visible (present + isDisplayed)
WebElement visible = wait.until(
    ExpectedConditions.visibilityOfElementLocated(WinBy.name("Ready")));

// Wait for element to be clickable (visible + isEnabled)
WebElement clickable = wait.until(
    ExpectedConditions.elementToBeClickable(WinBy.name("Save")));

// Custom condition with lambda
wait.until(d -> {
    WebElement el = d.findElement(WinBy.name("Status"));
    return el.getText().contains("Done") ? el : null;
});

WinJava选项

WinJavaOptions options = new WinJavaOptions()
    .setApp("C:\\Program Files\\MyApp\\app.exe")  // App to launch
    .setAppArguments("--flag value")              // Command line args
    .setAppWorkingDir("C:\\Working")              // Working directory
    .setWaitForAppLaunch(10)                      // Seconds to wait
    .setShouldCloseApp(true);                     // Close on quit

// Or attach to running app by window handle
WinJavaOptions options = new WinJavaOptions()
    .setAppTopLevelWindow("0x1A2B3C");            // Hex window handle

旧版Win32/VB6应用程序支持

WinJavaDriver会自动检测UI自动化不可见的遗留应用程序,并退回到其他发现方法。不需要配置,它只是工作。

VB6特殊处理

  • **雷霆\*控制** (ThunderRT6TextBox、ThunderRT6Combox等):标准UIA输入法在这些控件上会自动失败。WinJavaDriver检测Thunder\*类名并使用Win32消息。
  • VB6标签:尽管没有窗口句柄,但仍可发现。通过以下方式找到 WinBy.className("VB6Label").
// VB6 apps work the same as modern apps
WinJavaDriver driver = new WinJavaDriver(
    new WinJavaOptions().setApp("C:\\path\\to\\LegacyApp.exe"));

// VB6 Labels are discoverable
List labels = driver.findElements(WinBy.className("VB6Label"));
labels.forEach(l -> System.out.println(l.getText()));  // runtime captions

自定义服务器端点

WinJavaDriver使用自定义端点扩展了W3C WebDriver协议:

方法终点目的
得到/session/{id}/winjavadriver/element/{eid}/children获取直接子项(UIA+Win32/VB6)
得到/session/{id}/winjavadriver/windows/all列出系统上所有可见的窗口
得到/session/{id}/winjavadriver/screenshot/desktop完整桌面截图
职位/session/{id}/winjavadriver/grid/{eid}/cell创建虚拟MSFlexGrid单元元素
得到/session/{id}/winjavadriver/grid/{eid}/info获取网格尺寸并编辑字段信息
职位/session/{id}/winjavadriver/grid/{eid}/cell/value读取MSFlexGrid单元格值
PUT/session/{id}/winjavadriver/grid/{eid}/cell/value写入MSFlexGrid单元格值
  • 行/列从0开始(不包括标题行)
  • MCP服务器通过以下方式公开此信息 win_grid_edit 用于批量单元格编辑

MCP服务器(AI桌面自动化)

mcp/ 目录包含一个MCP服务器,该服务器使AI代理能够使用令牌高效的智能工具自动化Windows桌面应用程序。

设置

{
  "mcpServers": {
    "winjavadriver": {
      "command": "node",
      "args": ["
/mcp/dist/index.js"],
      "env": {
        "WINJAVADRIVER_PORT": "9515"
      }
    }
  }
}

构建MCP服务器:

cd mcp
npm install
npm run build

智能工具(AI优化)

这些工具将多个WebDriver调用组合成单个、令牌高效的操作:

工具说明
win_observe一次调用中的截图+元素摘要——主要的“查看屏幕”工具
win_explore简洁的元素摘要,位置为@(x,y),没有id警告
win_interact在一次调用中查找+操作(单击、键入、清除、clear_and_type、right_click、double_click和read)
win_batch按顺序执行多个查找和操作步骤(在一次调用中填写表单)
win_read_all从多个元素批量读取文本/属性
win_wait_for服务器端轮询(element_visible、element_gone、text_equals等)——等待期间令牌成本为零
win_diff显示自上次探索以来发生了什么变化(新的、删除的、更改的元素)
win_hover使用W3C Actions API将鼠标悬停在元素上
win_form_fields发现具有当前值的表单字段(编辑、组合框、复选框)
win_menu通过按顺序单击项目来导航菜单路径(例如,“文件”>“另存为”)
win_select_option从组合框/列表框中选择选项--展开、查找、单击
win_grid_edit在一次调用中批量编辑多个MSFlexGrid单元格

首选AI代理工作流程:

  1. win_observe --查看屏幕(屏幕截图+元素摘要)
  2. win_interactwin_batch --执行操作
  3. win_diffwin_observe --验证结果
  4. win_wait_for --当时间很重要时(对话框、加载)

标准工具

工具说明
win_launch_app使用可选功能启动应用程序 verbose: true 用于调试
win_attach_app通过窗口句柄连接到正在运行的应用程序
win_quit关闭会话和应用程序
win_find_element查找单个元素(名称、可访问性id、类名、标记名、xpath)
win_find_elements使用可选元素查找多个元素 includeInfo: true
win_click点击元素(支持x/y偏移)
win_type在元素中键入文本
win_clear清除元素值
win_send_keys发送具有重复语法的键盘按键(DOWN*5)
win_get_text获取元素文本
win_get_attribute获取元素属性
win_element_info获取元素信息(文本、矩形、类名、automationId、名称、启用、显示)
win_screenshot窗口、元素或整个屏幕的截图(fullscreen: true)
win_page_source以XML格式获取UI树
win_window_handle获取当前窗口句柄
win_list_windows列出当前进程的窗口句柄
win_list_all_windows列出所有可见窗口(标题、句柄、PID)
win_switch_window切换到其他窗口
win_set_window最大化、最小化或全屏
win_close_window关闭当前窗口
win_clipboard读/写系统剪贴板
win_get_logs获取服务器详细日志
win_set_verbose启用/禁用详细日志记录
win_clear_logs清除日志缓冲区
win_status检查服务器是否正在运行

服务器CLI

winjavadriver.exe [options]

Options:
  --port 
         Port to listen on (default: 9515)
  --host          Host to bind to (default: localhost)
  --verbose             Enable verbose logging
  --log-file 
     Write logs to file
  --inspect             Launch inspect mode (element spy)
  --version             Print version
  --help                Show help

通过Selenium Grid进行远程执行

使用Selenium Grid 4在远程Windows计算机上运行桌面UI测试。WinJavaDriver通过内置的中继功能进行集成,这与Appium使用的模式相同。

// Point tests at the Grid — routes to WinJavaDriver node automatically
WinJavaDriver driver = new WinJavaDriver(
    new URL("http://grid-machine:4444"), options);

有关完整的设置说明,请参阅 .

UWP应用程序(计算器、绘图等)

完全支持UWP应用程序:

// Launch Windows Calculator (UWP app)
WinJavaOptions options = new WinJavaOptions()
    .setApp("calc.exe")
    .setWaitForAppLaunch(10);

WinJavaDriver driver = new WinJavaDriver(options);

// Find and click button "Five"
driver.findElement(WinBy.name("Five")).click();
driver.findElement(WinBy.name("Plus")).click();
driver.findElement(WinBy.name("Three")).click();
driver.findElement(WinBy.name("Equals")).click();

// Get result
WebElement result = driver.findElement(WinBy.accessibilityId("CalculatorResults"));
System.out.println(result.getText()); // "Display is 8"

注: 对于UWP应用程序。, calc.exe)立即退出,实际应用程序作为不同的进程运行。WinJavaDriver会自动处理此问题。

从源头构建

客户端(Java)

cd client-java
mvn clean install

MCP服务器(Node.js)

cd mcp
npm install
npm run build

建筑

┌─────────────────────────────────────────────────────────┐
│                    Java Client                          │
│  WinJavaDriver (extends RemoteWebDriver)                │
│  WinBy → WebElement → WebDriverWait                     │
│  WinJavaDriverService (extends DriverService)           │
└─────────────────────┬───────────────────────────────────┘
                      │ W3C WebDriver Protocol
                      │ (HTTP + JSON)
┌─────────────────────▼───────────────────────────────────┐
│              winjavadriver.exe (server)                  │
│  Handles element discovery, interaction, screenshots    │
│  Supports UIA, Win32, MSAA, and VB6 controls            │
└─────────────────────────────────────────────────────────┘
client-java/                    (Java client extending Selenium RemoteWebDriver)
mcp/                            (MCP server for AI-driven automation)
examples/                       (Cucumber BDD test examples)
configs/                        (Selenium Grid Node TOML config templates)
scripts/                        (Node setup scripts)
jenkins/                        (Docker-based Jenkins CI/CD)
docs/                           (Documentation)

支持的控件类型

按钮、日历、复选框、组合框、自定义、DataGrid、数据项、文档、编辑、组、标题、HeaderItem、超链接、图像、列表、列表项、菜单、菜单栏、菜单项、窗格、进度条、单选按钮、滚动条、分隔符、滑块、旋转器、SplitButton、状态栏、选项卡、选项卡项、表、文本、拇指、标题栏、工具栏、工具提示、树、树项、窗口

示例项目

examples/ 目录包含完整的Cucumber BDD测试项目:

项目描述
calculator-testsWindows 11+VB6计算器自动化(3种情况)

运行示例

cd examples/calculator-tests
mvn test

该示例使用SeleniumHQ模式——没有硬编码路径,没有手动服务器管理:

// Each driver auto-discovers winjavadriver.exe and manages its own server
WinJavaDriver driver = new WinJavaDriver(
    new WinJavaOptions().setApp("calc.exe").setWaitForAppLaunch(10));
// ...
driver.quit();  // auto-stops the server

故障排除

未找到元素

  1. 使用检查器GUI验证元素是否存在并查看其属性
  2. 检查元素是否在其他窗口中--使用 driver.switchTo().window(handle)
  3. 为动态元素添加显式等待
  4. 尝试不同的定位器策略(accessibilityId最可靠)

会话创建失败

  1. 确保应用程序路径正确
  2. 检查应用程序是否需要提升权限
  3. 验证应用程序窗口是否在超时时间内出现

单击不起作用

  1. 确保元素可见且已启用
  2. 尝试使用 sendKeys("\n") 按钮
  3. 对于复杂的交互,请使用 Actions 类(右键单击、双击、悬停)

VB6 sendKeys不工作

VB6 Thunder\*控件忽略标准UIA输入法。WinJavaDriver会自动检测到这一点,并使用Win32消息。请注意,这将替换整个文本--call element.clear() 在链接多个之前 sendKeys() 电话。

详细日志

启用详细日志记录以调试问题:

WinJavaDriverService service = new WinJavaDriverService.Builder()
    .withVerboseLogging(true)
    .build();

贡献

欢迎投稿!请打开问题或拉取请求。

许可证

MIT许可证。看 许可证 文件。

目录标签

目录标签

Java云端部署Docker桌面自动化本地部署WebDriver协议Windows应用测试Java客户端UI自动化

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

session

工具数量(toolCount,工具数)

24

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明session部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP