コマンド ラインから実行中のWindows アプリケーションを検査して操作します。 UI テスト、デバッグ、自動化のために AI エージェントと開発者によって使用されます。
概要
winapp ui には、Windows アプリ UI を検査および操作するためのコマンドが用意されています。
Windows UI オートメーション (UIA) を使用します。 WPF、WinForms、Win32、Electron、WinUI 3 など、任意のWindows アプリで動作します。
ほとんどのコマンドは、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
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] に示されているセレクターを使用して要素をターゲットします。
セレクターには次の 3 種類があります。
| 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 セレクターは、 開発者セット識別子 (XAML でAutomationProperties.AutomationId )。
UI ツリー全体で AutomationId が一意である場合、 inspect し、セレクターとして直接表示 search 。これらは、レイアウトの変更、ローカライズ、ツリーの再構築に耐えられます。
一意の AutomationId が存在しない場合、スラッグ セレクター (btn-close-d1a0 など) が生成されます。
形式: prefix-name-hash。 ハッシュは要素 ID を検証しますが、UI の変更後に古くなる可能性があります。
出力形式を検査する
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)。
セマンティック スラッグ
ナメクジは、次の形式 prefix-normalizedname-hash 使用します。
- prefix — 3 文字の型の省略形 (btn、txt、chk、cmb、itm、tab、img、lbl、pn、win、grp、lnk、mnu など)
- normalizedname — AutomationId (推奨) または Name の小文字の英数字(最大 15 文字)
- hash — 要素の RuntimeId の 4 文字の 16 進ハッシュ (要素 ID を検証します)
スラッグはシェルセーフ (特殊文字なし)、一意であり、引数として直接使用できます。 ハッシュは、制約の検出を提供します。要素が置き換えられた場合は、"要素が変更された可能性があります。 検査を再実行します。"
name または AutomationId を持たない要素には、プレフィックス + ハッシュのみが表示されます (例: pn-c8a3)。
複数の一致のあいまいさを解消する
inspect
/
search出力からのスラッグは一意ですが、レイアウトの変更間で変更される可能性があります。複数の一致する場合は、プレーン型の名前またはテキストで使用します。 セレクターがあいまいな場合、CLI はすべての一致をそのナメクジと共に出力するため、適切なものを選択し、そのスラッグで再実行できます。
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
テキスト検索が複数の要素と一致する場合 (たとえば、Group、Button、Text がすべて同じ名前を共有する SettingsExpander など)、CLI は呼び出し可能な唯一の要素を自動的に選択します。 複数の呼び出し可能な場合は、すべての一致をスラッグで一覧表示します。
呼び出し不可能な検索結果 (たとえば、ボタン内の 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
コマンド
状態
アプリに接続し、接続情報を表示します。
winapp ui status -a notepad
winapp ui status -a notepad --json
検査
UI 要素ツリーを表示します。 出力は、階層の 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="..."編集可能な要素の現在のテキスト コンテンツ (名前と異なる場合)
検索
セレクターに一致する要素を検索します。 セマンティック スラッグを示す出力:
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)
出力に表示されるスラッグ (例: 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)
ダイアログまたはポップアップを開くと、すべてのウィンドウが 1 つの PNG に合成されるため、1 つの画像で完全な UI 状態を確認できます。
ポップアップ メニュー、ドロップダウン、ポップアップ、またはヒント オーバーレイをキャプチャする必要がある場合は、 --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 です。
クリックする
マウス シミュレーションを使用して、画面座標の要素をクリックします。 これは、 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
scroll-into-view
要素を表示領域までスクロールします。
winapp ui scroll-into-view itm-targetitem-c3d4 -a myapp
wait-for
要素が表示されるか、消えるか、値がターゲットに到達するまで待ちます。
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
get-focused
現在キーボード フォーカスがある要素を表示します。
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)
フレームワークのサポート
| フレームワーク | 検査 | 検索 | 呼び出す | set-value | スクリーンショット |
|---|---|---|---|---|---|
| WPF | ✅ 完全なツリー | ✅ すべてのプロパティ | ✅ すべてのパターン | ✅ | ✅ |
| WinForms | ✅ | ✅ | ✅ | ✅ | ✅ |
| Win32 の |
✅ | ✅ | ✅ | ✅ | ✅ |
| WinUI 3 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 電子 | ⚠️ Chromium ツリー | ⚠️ 制限あり | ⚠️ 異なる | ⚠️ 異なる | ✅ |
| Flutter | ⚠️ 基本 | ⚠️ 基本 | ❌ 最小限 | ❌ | ✅ |
Troubleshooting
| エラー | 原因 | ソリューション |
|---|---|---|
| "実行中のアプリが見つかりません" | アプリが実行されていないか、名前の不一致 | プロセス名を確認するか、PID を使用する |
| "複数のウィンドウの一致" | あいまいな -a 値 |
表示されているオプションの -w <HWND> を使用する |
| "複数のウィンドウがある" | プロセスに複数のウィンドウがある |
-w <HWND>を使用して特定のターゲットを設定する |
| "セレクターが一致した N 個の要素" | あいまいなレガシ セレクター |
inspect出力からスラッグを使用するか、レガシ セレクターに[1][0]を追加する |
| "要素が変更された可能性があります" | Slug ハッシュが現在の要素と一致しない |
inspectまたはsearchを再実行して新鮮なナメクジを取得する |
| "どの呼び出しパターンもサポートしていません" | 要素を呼び出すことはできません | 要素で inspect を使用して、呼び出し可能な子を検索する |
| "UIA ウィンドウが見つかりません" | UIA でプロセスが表示されない |
list-windowsを使用して HWND を検索し、次に-w |
| "Window has zero size" | ウィンドウが最小化されている | アプリは自動的に復元されます |
| スクリーンショットにないポップアップ/ドロップダウン | 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
[ファイル] ダイアログの操作
ファイルの開く/保存ダイアログは、UIA をサポートする標準的なWindows ダイアログです。
# 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 の && 演算子は、ネイティブ CLI が stderr に書き込んだり、ANSI エスケープ シーケンスを使用したりするとフリーズする可能性があります。 代わりに ; を使用します。各コマンドは無条件に実行され、このデッドロックを回避します。 これはエージェント ワークフローにも適しています。通常は、呼び出しに 0 以外の終了があった場合でも、スクリーンショットを実行する必要があります。
CI テスト パターン
スモーク テストと UI 検証には、CI パイプライン (GitHub Actions、Azure DevOps) で winapp ui コマンドを使用します。
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 出力を使用してアサートする
より複雑なアサーションには、PowerShell または jq で --json を使用します。
--jsonモードでのsearchおよびwait-forの終了コード コントラクト: 要素が一致しない (search) か、待機タイムアウト (wait-for) 場合、コマンドは完全に解析可能な結果エンベロープを stdout ({ "matchCount": 0, ... }または{ "found": false, "timedOut": true, ... }) に書き込み、終了コード 1 を返します。--jsonモードでは Stderr が空です (ロガー出力は抑制されます)。 エンベロープ フィールドまたは$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