Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Проверьте и взаимодействуйте с запущенными приложениями Windows из командной строки. Используется агентами ИИ и разработчиками для тестирования пользовательского интерфейса, отладки и автоматизации.
Обзор
winapp ui предоставляет команды для проверки и взаимодействия с Windows интерфейсами приложений.
Использует Windows модель автоматизации пользовательского интерфейса (UIA). Работает с любым приложением Windows — WPF, WinForms, Win32, Electron и WinUI 3.
Большинство команд управляют приложением с помощью шаблонов UIA (без внедрения входных данных); ui click — это исключение и используется реальное моделирование мыши для элементов управления, которые не поддерживаются InvokePattern.
Краткое руководство
# Connect to any app and see its UI tree
winapp ui inspect -a notepad
# Find specific elements
winapp ui search Button -a notepad
# Activate an element
winapp ui invoke Close -a notepad
# Take a screenshot
winapp ui screenshot -a notepad
Целевые приложения
По имени процесса
winapp ui inspect -a notepad
winapp ui inspect -a slack # auto-picks visible window for multi-process apps
winapp ui inspect -a imageresizer # partial match: finds PowerToys.ImageResizer
По заголовку окна
winapp ui inspect -a "LICENSE - Notepad"
winapp ui inspect -a "Fix WinApp" # partial title match
By PID
winapp ui inspect -a 12345
HWND (стабильный — выживает изменения табуляции или заголовка)
# Discover HWNDs
winapp ui list-windows -a Terminal
→ HWND 985238: "🤖 Testing" (WindowsTerminal, PID 21228)
→ HWND 131906: "Fix WinApp" (WindowsTerminal, PID 21228)
# Target specific window
winapp ui inspect -w 131906
winapp ui screenshot -w 131906
Используется -a для обнаружения для -w стабильного целевого объекта. При -a совпадении с несколькими окнами команда выводит их с помощью HWND для выбора.
Селекторы
Целевые элементы с помощью селектора, показанного в [brackets] результатах проверки и поиска.
Существует три типа селекторов:
| Selector | Значение | Example |
|---|---|---|
MinimizeButton |
AutomationId (показано, когда уникальный — стабильный, предпочтительный) | winapp ui invoke MinimizeButton -a myapp |
btn-close-d1a0 |
Семантическая семантическая слизь (показана, если уникальный идентификатор AutomationId) | winapp ui invoke btn-close-d1a0 -a myapp |
Submit |
Поиск по запросу Name/AutomationId (подстрока без учета регистра) | winapp ui invoke Submit -a myapp |
Селекторы AutomationId — это идентификаторы наборов разработчиков (AutomationProperties.AutomationId в XAML).
Когда automationId является уникальным для всего дерева пользовательского интерфейса и inspectsearch отображает его непосредственно в качестве селектора— они сохраняют изменения макета, локализацию и реструктуризацию деревьев.
Селекторы slug (например, btn-close-d1a0) создаются при отсутствии уникального идентификатора automationId.
Формат: prefix-name-hash. Хэш проверяет удостоверение элемента, но может оказаться устаревшим после изменений пользовательского интерфейса.
Проверка формата выходных данных
В inspect команде показано дерево элементов с цветными выходными данными (селектор в циане, имя в зеленом цвете, метаданные в сером цвете):
TabView Tab (0,-1 1200x48)
TabListView List (4,-1 1100x48)
tab-newtab-5f5b TabItem "New Tab" (14,-1 200x48)
NewTabButton SplitButton "New Tab" [collapsed] (1104,5 96x36)
Found 10 elements (--depth 3). Use the first token as selector, e.g.: winapp ui invoke TabView -a terminal
Первое слово в каждой строке — это селектор— использовать его с другими ui командами.
Если элемент имеет уникальный AutomationId, он используется напрямую (например, TabView, NewTabButton).
Если уникальный automationId не существует, используется созданный слизь (например, tab-newtab-5f5b).
Семантические слизи
Slugs использует формат: где: prefix-normalizedname-hash
- префикс — сокращение типа 3 букв (btn, txt, chk, cmb, itm, tab, img, lbl, pn, win, grp, lnk, mnu и т. д.)
- нормализованное имя — буквенно-цифровые буквы нижнего регистра из AutomationId (предпочтительно) или name, максимум 15 символов
- hash — хэш 4-char шестнадцатеричного хэша элемента RuntimeId (проверяет удостоверение элемента)
Slugs — это оболочкобезопасные (без специальных символов), уникальные и могут использоваться непосредственно в качестве аргументов. Хэш обеспечивает обнаружение устаревших данных— если элемент был заменен, вы получите сообщение "Элемент, возможно, изменился. Повторно выполните проверку".
Элементы без имени или AutomationId отображают только префикс + хэш (например, pn-c8a3).
Диамбигирование нескольких совпадений
Слизи из inspect/search выходных данных уникальны, но могут изменяться между изменениями макета. Используйте их над именами обычного типа или текстом при нескольких совпадениях. Если селектор неоднозначный, интерфейс командной строки печатает все совпадения со своими слизями, чтобы вы могли выбрать правильный и повторно запустить с этим слизь.
winapp ui search Button -a myapp # shows: btn-ok-a1b2 "OK", btn-cancel-c3d4 "Cancel"
winapp ui invoke btn-ok-a1b2 -a myapp # invoke using slug (preferred)
winapp ui invoke btn-cancel-c3d4 -a myapp # invoke the other Button by its slug
Поиск обычного текста
Используйте обычный текст для поиска элементов — не требуется специального синтаксиса:
winapp ui search Minimize -a notepad # finds elements with "Minimize" in Name or AutomationId
winapp ui search Close -a notepad # case-insensitive substring match
winapp ui invoke Minimize -a notepad # search + invoke in one step (disambiguates if needed)
winapp ui search "Save" -a notepad # find elements containing "Save"
winapp ui search "error" -a myapp # case-insensitive match
Если поиск текста совпадает с несколькими элементами (например, SettingsExpander, где Group, Button и Text все используют одно и то же имя), интерфейс командной строки автоматически выбирает единственный вызываемый элемент. Если несколько вызываются, он перечисляет все совпадения со слизями.
Для не вызываемых результатов поиска (например, TextBlock внутри кнопки) поиск автоматически обнажает ближайшего вызываемого предка — родительский элемент, с invokeкоторым можно использовать.
Это работает для всех селекторов поиска:
lbl-savechanges-a1b2 "Save changes" (120,40 80x20)
^ invoke via: btn-save-c3d4 "Save"
Селектор поверхности можно использовать напрямую:
winapp ui invoke btn-save-c3d4 -a myapp # invoke the parent Button
Commands
статус
Подключитесь к приложению и отображение сведений о подключении.
winapp ui status -a notepad
winapp ui status -a notepad --json
Проверить
Просмотр дерева элементов пользовательского интерфейса. Выходные данные показывают семантические семантические отступы с отступом в 2 пробела для иерархии:
winapp ui inspect -a notepad # full window tree, depth 3
winapp ui inspect -a notepad --depth 5 # deeper tree
winapp ui inspect txt-searchbox-e5f6 -a notepad # subtree rooted at element
winapp ui inspect --ancestors btn-close-d1a2 -a notepad # walk up from element to root
winapp ui inspect -a myapp --interactive # invokable elements only, auto-depth 8
winapp ui inspect -a myapp --hide-disabled # hide disabled elements
winapp ui inspect -a myapp --hide-offscreen # hide offscreen elements
Пример выходных данных (по умолчанию):
win-aidevgalleryp-f1a3 "AI Dev Gallery Preview" (94,206 1280x1023)
pn-c8a3 (102,207 1264x1014)
btn-minimize-d1a0 "Minimize" (1222,206 48x48)
btn-maximize-e2b1 "Maximize" (1270,206 48x48)
itm-samples-3f2c "Samples" (102,330 72x62)
Пример выходных данных (--interactive — только вызываемые элементы, неструктурированный список):
btn-minimize-d1a0 "Minimize" (1222,206 48x48)
btn-maximize-e2b1 "Maximize" (1270,206 48x48)
btn-close-d1a2 "Close" (1318,206 48x48)
itm-home-7b3e "Home" (102,268 72x62)
itm-samples-3f2c "Samples" (102,330 72x62)
itm-models-9a4f "Models" (102,392 72x62)
Элементы могут отображать эти маркеры состояния:
-
[on]/[off]/[indeterminate]— состояние переключателя или флажка -
[collapsed]/[expanded]— расширение и свертывание состояния для деревьев, полей со списком, элементов меню -
[scroll:v]/[scroll:h]/[scroll:vh]— прокручиваемый контейнер (вертикальный, горизонтальный или оба) -
[offscreen]— элемент не отображается на экране -
[disabled]— элемент не включен -
value="..."— текущее текстовое содержимое для редактируемых элементов (если отличается от имени)
search
Поиск элементов, соответствующих селектору. Выходные данные показывают семантические слизи:
winapp ui search Button -a notepad # all buttons
winapp ui search Close -a notepad # finds elements with "Close" in name
winapp ui search SearchBox -a notepad # finds elements with "SearchBox" in name or AutomationId
winapp ui search Button --max 10 -a notepad # limit results
Пример выходных данных:
btn-minimize-d1a0 "Minimize" (1222,206 48x48)
btn-maximize-e2b1 "Maximize" (1270,206 48x48)
btn-close-d1a2 "Close" (1318,206 48x48)
Slugs, отображаемые в выходных данных (например, btn-minimize-d1a0) можно использовать непосредственно с другими командами:
winapp ui invoke btn-minimize-d1a0 -a notepad
get-property
Чтение значений свойств из элемента. Включает состояние, зависящее от шаблона (ToggleState, Value, IsSelected и т. д.).
winapp ui get-property btn-submit-7a90 -a myapp # all properties
winapp ui get-property chk-checkbox-b2c3 -p ToggleState -a myapp # checkbox state
winapp ui get-property txt-textbox-a4b1 -p Value -a myapp # current text value
winapp ui get-property cmb-combobox-d5e6 -p ExpandCollapseState -a myapp # expanded or collapsed
снимок экрана
Захват окна или элемента в формате PNG. Если существует несколько окон (например, приложение + открытое диалоговое окно), они композитируются в один PNG с каждой стежкой окна.
winapp ui screenshot -a notepad # saves screenshot.png in cwd
winapp ui screenshot -a notepad --output my.png # custom filename
winapp ui screenshot -a notepad --json # returns file path as JSON
winapp ui screenshot -w 131906 # target specific HWND (+ its dialogs)
winapp ui screenshot txt-searchbox-e5f6 -a myapp # crop to element bounds
winapp ui screenshot -a myapp --capture-screen # capture from screen (includes popups/overlays)
При открытии диалоговых окон или всплывающих окон все окна составятся в один PNG, чтобы увидеть полное состояние пользовательского интерфейса на одном изображении.
Используйте --capture-screen , когда необходимо записать всплывающие меню, раскрывающийся список, всплывающие элементы или наложения подсказки. В --capture-screen режиме (и при попытке после обнаружения пустого кадра) целевое окно будет доставлено на передний план в первую очередь; обычное окно не перемещает окно.
Вызова
Программным образом активируйте элемент (нажмите кнопку, установите флажок, разверните поле со списком).
winapp ui invoke btn-submit-7a90 -a myapp # by slug from inspect
winapp ui invoke btn-submit-a1b2 -a myapp # by slug from inspect/search
winapp ui invoke cmb-sizecombobox-b4c5 -a myapp # expand combo box
Пытается выполнить попытку шаблонов: InvokePattern → TogglePattern → SelectionItemPattern → ExpandCollapsePattern.
click
Щелкните элемент в координатах экрана с помощью имитации мыши. Используйте это для элементов управления, которые не поддерживают InvokePattern (например, заголовки столбцов, элементы списка).
winapp ui click btn-column1-a3f2 -a myapp # single click by slug
winapp ui click "Column1" -a myapp # single click by text search
winapp ui click btn-column1-a3f2 -a myapp --double # double-click
winapp ui click btn-column1-a3f2 -a myapp --right # right-click
set-value
Задайте значение для редактируемого элемента (текст для TextBox/ComboBox, число для ползунка).
winapp ui set-value txt-textbox-a4b1 "Hello world" -a notepad
winapp ui set-value sld-volume-b2c3 75 -a myapp
get-value
Чтение текущего значения из элемента. Использует смарт-резервную цепочку: TextPattern (RichEditBox, Document) → ValuePattern (TextBox, Slider) → SelectionPattern (ComboBox, RadioButton, TabView) → имя (метки).
winapp ui get-value doc-texteditor-53ad -a notepad # read full document text
winapp ui get-value SearchBox -a myapp # read TextBox content
winapp ui get-value CmbTheme -a myapp # read ComboBox selected item
winapp ui get-value sld-volume-b2c3 -a myapp # read Slider value
winapp ui get-value lbl-title-a1b2 -a myapp --json # JSON: { "elementId": "...", "text": "..." }
концентрация
Переместите фокус клавиатуры на элемент.
winapp ui focus txt-textbox-a4b1 -a notepad
прокрутка в представление
Прокрутите элемент в видимой области.
winapp ui scroll-into-view itm-targetitem-c3d4 -a myapp
ожидание
Подождите, пока элемент появится, исчезнет или имеет значение, достигающее целевого объекта.
winapp ui wait-for Button -a myapp --timeout 5000 # wait for any button
winapp ui wait-for btn-submit-7a90 -a myapp --timeout 5000 # wait for specific element
winapp ui wait-for CounterDisplay -a myapp --value "5" --timeout 5000 # wait for element value (smart fallback)
winapp ui wait-for lbl-status -a myapp --property Name --value "Done" --timeout 5000 # wait for specific property
winapp ui wait-for btn-submit-a1b2 --gone -a myapp --timeout 2000 # wait for element to disappear
winapp ui wait-for lbl-status -a myapp --value "Done" --contains # substring match instead of exact equality
Прокрутки
Прокрутите элемент контейнера. Найдите прокручиваемые контейнеры с search scroll помощью — найдите [scroll:v] (вертикальные) или [scroll:h] (горизонтальные) маркеры.
# Find which elements are scrollable and in which direction
winapp ui search scroll -a myapp
# pn-scrollview-bfef Pane "scrollView" [scroll:v] (main content, vertical)
# pn-scrollviewer-bfb1 Pane "scrollViewer" [scroll:h] (horizontal list)
# Scroll the main content down
winapp ui scroll pn-scrollview-bfef --direction down -a myapp
# Jump to top/bottom
winapp ui scroll pn-scrollview-bfef --to bottom -a myapp
# If you target an element that's not scrollable, scroll walks up to find the nearest scrollable parent
winapp ui scroll itm-someitem-a1b2 --direction down -a myapp
получение фокуса
Отображение элемента с фокусом клавиатуры.
winapp ui get-focused -a myapp
List-windows
Вывод списка всех видимых окон для приложения, включая всплывающие окна и диалоговые окна.
winapp ui list-windows -a imageresizer
winapp ui list-windows -a Terminal
winapp ui list-windows # all windows (no filter)
Поддержка платформы
| Платформа | Проверить | search | Вызова | set-value | снимок экрана |
|---|---|---|---|---|---|
| WPF | ✅ Полное дерево | ✅ Все свойства | ✅ Все шаблоны | ✅ | ✅ |
| WinForms | ✅ | ✅ | ✅ | ✅ | ✅ |
| Вин32 | ✅ | ✅ | ✅ | ✅ | ✅ |
| WinUI 3 | ✅ | ✅ | ✅ | ✅ | ✅ |
| Электрон | ⚠️ Дерево Chromium | ⚠️ Ограничено | ⚠️ Зависит | ⚠️ Зависит | ✅ |
| Flutter | ⚠️ Базовый | ⚠️ Базовый | ❌ Минимальный | ❌ | ✅ |
Troubleshooting
| Error | Причина | Решение |
|---|---|---|
| "Не найдено работающего приложения" | Несоответствие имени приложения или не выполняется | Проверка имени процесса или использование PID |
| "Совпадение с несколькими окнами" | Неоднозначное -a значение |
Использование -w <HWND> из перечисленных параметров |
| "имеет несколько окон" | Процесс содержит несколько окон | Использование -w <HWND> для целевой конкретной. |
| "Селектор совпадает с элементами N" | Неоднозначный селектор прежних версий | Использование slugs из inspect выходных данных или добавления [0]к [1] устаревшим селекторам |
| "Элемент, возможно, изменился" | Хэш slug не соответствует текущему элементу | Повторное выполнение inspect или search получение свежих слизей |
| "не поддерживает какой-либо шаблон вызова" | Не удается вызвать элемент | Использование inspect элемента для поиска вызываемого дочернего элемента |
| "Окно UIA не найдено" | UIA не может видеть процесс | Используйте list-windows для поиска HWND, а затем -w |
| "Окно имеет нулевой размер" | Окно свернуто | Приложение будет автоматически восстановлено |
| Всплывающее окно или раскрывающееся меню не на снимке экрана | PrintWindow не фиксирует наложения | Использование --capture-screen флага |
Общие шаблоны
Навигация и проверка
winapp ui invoke btn-settings-a1b2 -a myapp # click a button
winapp ui wait-for pn-settingspage-c3d4 -a myapp # wait for page to load
winapp ui screenshot -a myapp --output settings.png # verify visually
Поиск текста и вызов родительского элемента
# Search shows invokable ancestor; invoke auto-walks to it
winapp ui invoke 'Save changes' -a myapp
# Or search first to see what matches, then invoke
winapp ui search "Save changes" -a myapp; winapp ui invoke btn-save-c3d4 -a myapp
Диамбигуат повторяющихся элементов
winapp ui search '#Image' -a myapp; winapp ui invoke itm-image-a2b3 -a myapp
Снимок экрана: всплывающие наложения
winapp ui set-value txt-searchbox-e5f6 "query" -a myapp; winapp ui screenshot -a myapp --capture-screen
Навигация, ожидание и проверка (одна цепочка)
winapp ui invoke btn-settings-a1b2 -a myapp; winapp ui wait-for pn-settingspage-c3d4 -a myapp --timeout 3000; winapp ui screenshot -a myapp -o settings.png
Обнаружение, щелчки и проверка
winapp ui inspect -a myapp --interactive; winapp ui invoke btn-submit-7a90 -a myapp; winapp ui screenshot -a myapp
Диалоговое окно "Файл"
Диалоговые окна открытия и сохранения файлов — это стандартные диалоговые окна Windows с поддержкой UIA:
# Trigger the dialog, find it, type the path, confirm
winapp ui invoke btn-openfilebtn-a2b3 -a myapp
winapp ui list-windows -a myapp # find dialog HWND
winapp ui set-value txt-1148-c4d5 "C:\path\to\file.png" -w <dialog-hwnd>
winapp ui invoke btn-open-e6f7 -w <dialog-hwnd>
Используется inspect -w <dialog-hwnd> --interactive для обнаружения фактических слизей для определенного диалогового окна.
Почему ; для цепочки (не &&)
Оператор PowerShell && может заморозить, когда собственный интерфейс командной строки записывает в stderr или использует escape-последовательности ANSI. Используйте ; вместо этого — он выполняет каждую команду без каких-то условий и избегает этой взаимоблокировки. Это также лучше для рабочих процессов агента: обычно требуется запустить снимок экрана, даже если вызов ненулевым выходом.
Шаблоны тестирования CI
Используйте команды winapp ui в конвейерах CI (GitHub Actions, Azure DevOps) для тестов дыма и проверки пользовательского интерфейса.
wait-for с --property утверждением и --value выступает в качестве утверждения — он возвращает код выхода 1 во время ожидания, не выполняя автоматический шаг CI.
Запуск и тестирование в GitHub Actions
steps:
- name: Build
run: dotnet build MyApp.csproj -c Debug -p:Platform=x64
- name: Launch and test
run: |
$result = winapp run .\bin\x64\Debug\net8.0-windows10.0.26100.0\win-x64 --detach --json | ConvertFrom-Json
$appPid = $result.ProcessId
# Wait for window to initialize
winapp ui wait-for "Main Window" -a $appPid --timeout 30000
# Run tests — each wait-for exits non-zero on failure
winapp ui invoke "Login" -a $appPid
winapp ui wait-for "Dashboard" -a $appPid --timeout 10000
winapp ui screenshot -a $appPid -o dashboard.png
Состояние элемента Assert с wait-for
wait-for --value опросы до тех пор, пока значение элемента не соответствует ожидаемой строке, используя ту же интеллектуальную резервную строку, что get-value и (TextPattern → ValuePattern → SelectionPattern → Name). Возвращает код выхода 0 в совпадении, код выхода 1 во время ожидания— что делает его понятным утверждением CI. Используйте --property для проверки определенного свойства UIA.
# Assert: button click updated the counter (smart value fallback — works for TextBlock, TextBox, etc.)
winapp ui invoke "Counter Button" -a $pid
winapp ui wait-for "Counter Display" -a $pid --value "Count: 1" -t 5000
# Assert: text input was accepted
winapp ui set-value "Search Box" "hello world" -a $pid
winapp ui wait-for "Search Box" -a $pid --value "hello world" -t 3000
# Assert: checkbox was toggled (use --property for specific UIA properties)
winapp ui invoke "Dark Mode" -a $pid
winapp ui wait-for "Dark Mode" -a $pid --property ToggleState --value "On" -t 3000
# Assert: navigation happened (new page appeared)
winapp ui invoke "Settings" -a $pid
winapp ui wait-for "Settings Page" -a $pid -t 10000
# Assert: dialog was dismissed (element disappeared)
winapp ui invoke "Close" -a $pid
winapp ui wait-for "Dialog Title" -a $pid --gone -t 5000
Утверждение с выходными данными JSON
Используйте --json PowerShell или jq для более сложных утверждений:
Контракт exit-code для
searchиwait-forв--jsonрежиме: если элемент не совпадает () или время ожидания (searchwait-for), команда записывает полностью синтаксический конверт результата в stdout ({ "matchCount": 0, ... }или{ "found": false, "timedOut": true, ... }) и возвращает код выхода 1. Stderr пуст в--jsonрежиме (выходные данные средства ведения журнала подавляются). Ветвь на полях конверта или в$LASTEXITCODEзависимости от того, какая из них более эргономна.
# Assert: search found exactly one match
$result = winapp ui search "Submit" -a $pid --json | ConvertFrom-Json
if ($result.matchCount -ne 1) { throw "Expected 1 Submit button, found $($result.matchCount)" }
# Assert: element has expected properties
# inspect --json returns { windows: [{ hwnd, title, elements: [...] }] };
# each window's elements[] is the nested tree (children rendered via .children).
$tree = winapp ui inspect "Counter Display" -a $pid --json | ConvertFrom-Json
$counter = $tree.windows[0].elements[0]
if ($counter.name -ne "Count: 3") { throw "Counter value wrong: $($counter.name)" }
Полный пример теста дыма
# Launch
$app = winapp run .\build-output --detach --json | ConvertFrom-Json
# Verify app loaded
winapp ui wait-for "Main Page" -a $app.ProcessId -t 30000
# Interact and assert
winapp ui invoke "Add Item" -a $app.ProcessId
winapp ui set-value "Item Name" "Test Item" -a $app.ProcessId
winapp ui invoke "Save" -a $app.ProcessId
winapp ui wait-for "Test Item" -a $app.ProcessId -t 5000 # assert item appeared in list
winapp ui wait-for "Save" -a $app.ProcessId --gone -t 3000 # assert save dialog closed
# Visual verification
winapp ui screenshot -a $app.ProcessId -o smoke-test.png
Windows developer