コマンド ラインから実行中のWindows アプリケーションを検査して操作します。 UI テスト、デバッグ、自動化のために AI エージェントと開発者によって使用されます。
概要
winapp ui には、Windows アプリ UI を検査および操作するためのコマンドが用意されています。
Windows UI オートメーション (UIA) を使用します。 WPF、WinForms、Win32、Electron、WinUI 3 など、任意のWindows アプリで動作します。
ほとんどのコマンドは、UIA パターン (入力インジェクションなし) によってアプリを駆動します。 例外は、実際の入力を挿入します。 ui click/ui hover/ui drag マウス シミュレーションを使用 ui touch/ui pen 、タッチとペン/スタイラスの入力を合成し、 ui send-keys はキーボード入力を合成します。UIA パターンでは駆動できないコントロールとシナリオに対応します。
Important
対話型デスクトップの要件 (入力挿入動詞)。OS レベルの入力をclick、hover、drag、touch、pen、scroll --wheel、send-keys --via send-input合成するため、ロック解除された対話型デスクトップとターゲット ウィンドウがフォアグラウンドに必要です。
ロックされたワークステーションまたはセキュリティで保護されたデスクトップ (LogonUI/UAC) では、(昇格/no_interactive_desktopの場合とは異なり) foreground_not_targetで高速に挿入および失敗することはできません。
touch
/
penさらに、ウィンドウが解決されない場合 (no_target)、ターゲット ウィンドウの外側の座標は致命的でない警告 (warnings[]の下の--jsonエントリ、またはテキスト モードの警告行) であり、マウス動詞と一致するインジェクションが続行されます。 それ以外のすべてのもの ( inspect、 search、 get-property、 get-value、 wait-for、 set-value、 invoke、 scroll --direction/--to ) は、UIA パターンを通じてアプリを駆動し、 ヘッドレス/ロック セッションフレンドリです。
screenshot は、非挿入動詞の例外です。排他的ターンを取り、そのキャプチャには使用可能な対話型デスクトップが必要になる場合があります。これは、エンジンが最小化されたターゲットを復元し、フレーム キャプチャが使用できない場合や --capture-screen が使用されたときにフォアグラウンドにフォールバックするためです。 CI では UIA パターン動詞を優先します。実際の入力が本当に必要なシナリオでは、インジェクション動詞を予約します。 挿入する前に、ジェスチャ動詞も ターゲット要素を再解決 し、空き領域に入力をランディングするのではなく、まだアニメーション化/再配置している場合は target_moved で拒否します。
クイック スタート
コア ループの winapp ui --help を実行します。 inspect -a <app> --interactive して、何に対処できるかを確認し、動作する invoke または set-value を確認し、結果を確認 get-value 。 すべてのコマンドの --help に例が示されています。
winapp ui dumpなどの不明なコマンドはコード 1 で終了し、最も近いコマンドを提案します (--jsonを渡すときにsuggestionsを含む JSON エラーとして)。
# 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
Windows サンドボックスでの UI オートメーションの実行
デスクトップから自動化を維持するには、実行コマンドと UI コマンドに --on sandbox を追加します。
winapp run . --on sandbox --detach
winapp ui inspect --on sandbox -a MyApp
winapp ui invoke --on sandbox SubmitButton -a MyApp
--detach 起動後に戻ります。ない場合、 run はアプリが終了するまで待機します。 PID またはウィンドウ ハンドルを使用するゲスト コマンドを含め、すべてのゲスト コマンドで --on sandbox を維持します。
クライアント要件、簡単なセットアップ/再接続フォーカスの変更、ワークフロー調整、ホスト出力配信については、Windowsサンドボックスの実行に関するページを参照してください。
スコープ付きクエリと型指定されたクエリ
winapp ui search "Welcome to MyApp" -a myapp --root MailRow --type Text --class-name TextBlock
winapp ui get-value Subject -w 123456 --root MailRow --type TextBox
winapp ui get-property Subject -a myapp --root MailRow --type Edit --property Value
winapp ui wait-for Subject -a myapp --root MailRow --type Edit --value "Ready" --timeout 10000
winapp ui invoke Open -w <dialog-HWND> --type Button
winapp ui set-value "Text editor" "hello" -a notepad --type Document
これらのコマンドは、要素セレクター (セレクター付き)、 inspect 、 search、 get-property、 get-value、 wait-for、 invoke、 set-value、 click、 focus、 hover、 scroll、 scroll-into-view、 screenshot、 record、 touch、および penの省略可能なフィルターを受け入れます。
drag (2 つのセレクター) と send-keys --target しません。
セレクターと指定されたすべてのフィルターは 、同じ要素と一致する必要があります。 フィルターはセレクターを絞り込むので、セレクターが省略可能な inspect、 screenshot、および recordは、フィルターを指定しないと invalid_arguments で失敗します。
touchとpenの場合、フィルターにはセレクターが必要です。フィルターを--atまたは--path (invalid_arguments) と組み合わせることはできません。
-
--root <selector>では、一意に一致する 1 つのルートの子孫のみが検索され、ルート自体は検索されません。 あいまいさを解消するには、AutomationId またはinspectからのスラッグを使用します。 複数の要素に一致するルートは、1 つの一致が呼び出し可能であっても、ambiguous_selectorで失敗します。 ルートが見つからないと、一致は生成されません。 ルートが見つかると、子孫が一致しない場合でも、クエリは関連のないポップアップ ウィンドウを検索しません。 クエリは、inspectの表示深度によって制限されません。 -
--type <control-type>は UIA コントロール型と一致し、大文字と小文字は区別されません。 エイリアスはTextBox→EditとTextBlock→Textだけです。 不明な名前 (数値 ID やワイルドカード式を含む) は、invalid_argumentsで失敗します。 -
--class-name <literal>は、プロバイダーの UIAClassName全体に一致し、大文字と小文字は区別されません。 部分文字列、ワイルドカード、または正規表現ではありません。get-property --property ClassNameを使用してプロバイダーの値を検出します。クラス名は UIA コントロール型と等しい必要はありません。
フィルター処理されたクエリでは、UIA の コントロール ビュー ( inspectで表示されるのと同じビュー) が使用されます。
生ビューでのみ公開されているプロバイダー ノードは返されません。 inspect を使用して、含まれているコントロールとそのセレクターを見つけます。
41 の公式の種類がすべてサポートされています: Button、 Calendar、CheckBox、ComboBox、Edit、Hyperlink、Image、ListItem、List、Menu、MenuBar、MenuItem、ProgressBar、RadioButton、ScrollBar、Slider、Spinner、StatusBar、Tab、TabItem、Text、 ToolBar、ToolTip、Tree、TreeItem、Custom、Group、Thumb、DataGrid、DataItemDocument、SplitButton、Window、Pane、Header、HeaderItem、Table、TitleBar、SeparatorSemanticZoom、。
wait-for では、 すべてのポーリングでルート セレクターが再び解決されるため、コマンドの開始後にルートが表示される可能性があります。
--goneでは、存在しないルートは、一致する子孫がないことを意味します。あいまいなルートはエラーであり、成功ではありません。
割り込まれた参照は消失の証拠ではありません。参照中に要素が削除されたり、 --value 読み取り前に置き換えられたりすると、次のポーリングが再度チェックされます。他の参照エラーまたは読み取りエラーはコマンドに失敗します。
-w <HWND> は、ルート検出をそのウィンドウの UIA ツリーに制限します。
-aを使用すると、ルート検出でアプリのポップアップ ウィンドウを見つけることもできます。 完全ルート AutomationId の一致は、すべてのウィンドウで部分文字列の一致よりも優先されます。複数の完全一致は、 ambiguous_selectorで失敗します。
ルート スラッグは、別のウィンドウに同じ AutomationId がある場合でも、その要素を選択します。 選択したルートが置き換えられると、古いスラッグは一致しなくなります。代わりにポーリングする場合は、AutomationId または名前ルートを使用します。
フィルターが存在する場合、 search を除くすべてのコマンドは、複数の要素が残っている場合は ambiguous_selector で失敗します。フィルターを絞り込むか、一意のスラッグを使用します。 要素数に対して動作するコマンドは、検索するすべてのウィンドウで一致するため、所有するダイアログの一致するコントロールもセレクターをあいまいにします。 正確な AutomationId の一致は、フィルター処理されたスコープ内の部分文字列の一致よりも優先されます。 3 つのオプションをすべて省略すると、既存のクエリ動作が保持されます。
同時実行 UI ワークフローの調整
Windowsには、前景ウィンドウが 1 つ、キーボード フォーカスが 1 つ、カーソルが 1 つ、入力ストリームが 1 つだけです。 2 つの winapp ui ワークフローが同じサインインしたデスクトップで同時に実行されると、互いにフォーカスを盗んだり、開いたメニューを閉じるか、保留中のクリックの下からターゲットを移動したりできます。
仲裁は常にオンです。 物理デスクトップに触れるすべての winapp ui コマンドは、セットアップもオフにする方法もないため、2 つのエージェントが互いのウィンドウに入力することはできません。 読み取り専用コマンドは同時に実行されます。 1 つの例外は、winapp の調整フォルダー ( %USERPROFILE%\.winappをブロックするエージェント サンドボックスなど) にアクセスできないプロセスです。そのコマンドは引き続き実行されますが、順番に実行されず、警告を出力します ( --json または --quietを除く)。
コマンド間の継続性はオプトインです。 既定では、各コマンドは自己完結型のワンショットです。ターンを待機し、作業を行い、すぐにデスクトップを解放します。 複数のコマンドにわたってデスクトップを保持するには、すべて同じワークフロー ID を指定します。
# Set once per logical UI workflow
$env:WINAPP_UI_WORKFLOW_ID = [guid]::NewGuid().ToString()
必要な知識:
- ワークフロー ID は、1 つの論理ワークフロー (必ずしもエージェント全体ではなく、必ずしも 1 つのアプリ) に名前を付けます。 コマンドの連携には 同じ 値を使用します (記録と、キャプチャする必要があるクリック)。は、1 つのエージェントが両方を起動した場合でも、独立したワークフローに 異なる 値を使用します。
- ID がない場合、すべてのコマンドは独立したワンショットです。 それはまだ仲裁しますが、それは恵みをバンクせず、それが終わった瞬間にデスクトップを手放します。 2 つの no-id コマンドは、同じシェルから起動した場合でも個別のワークフローです。
- Fresh-shell ホストとアダプティブ ホストは、同じ値を挿入する必要があります。 各コマンドが新しいシェル (ほとんどのエージェント ツール呼び出しのしくみ) で実行される場合、それらをグループ化できるのは、すべての連携呼び出しに明示的な
WINAPP_UI_WORKFLOW_ID渡すことだけです。 - 4 秒の猶予期間は、モデルの推論ではなく、タイトなバーストを保護します。 ID を持つワークフローは、次のコマンドが 4 秒以内に開始される限り、そのターンを維持します。 これは、1 つのスクリプト内のバックツーバック コマンドについて説明します。モデルが考えている間、意図的に期限切れになります。 これは、完了したと言えない場合のフォールバックです。可能な場合は、
winapp ui yieldを実行して待つ代わりに実行します。 - アダプティブ ワークフローは、再取得、再検証、再生を行う必要があります。 別のワークフローがデスクトップを使用している可能性がある理由のギャップの後、メニューを再度開き、要素を再解決してから、操作します。考えている間にデスクトップを保持するのではなく、既知のエンドツーエンドのシーケンスを 1 つのタイトなスクリプトとして送信します。
- 順序付けは、最初に所有者アフィニティ、次に FIFO です。 ワークフローがアクティブであるか、その猶予期間にある間、他のワークフローが既に待機している場合でも、コマンドを発行し続ける可能性があります。
winapp ui yield実行されるか、猶予期間が切れると、待機中のワークフローは厳密な到着順序で処理されます。 したがって、1 つのワークフローによる継続的なアクティビティは、他のワークフローを無期限に遅延させることができます。 - ハードキャップはありません。 長いスクリプト、無制限の記録、または障害ループによって、他の変更ワークフローがブロックされる可能性があります。
-
キャンセルまたはプロセスの終了は、 スタックしたライブ ワークフローの復旧です。 待機中のコマンドは 1 秒後に状態を出力し、
130終了するCtrl+Cで停止できます。 - 互換性のある更新されたバイナリのみが連携します。 古い
winappは、この機能より前のビルドであり、調整されていません。 UI オートメーション NuGet パッケージを直接呼び出すコードは、この保証の範囲外です。調整はパッケージではなく CLI に存在します。
ターンを待機するコマンドは次のとおりです。
| Behavior | Commands |
|---|---|
| 同時に実行 (待機しない) |
status、 list-windows、 inspect、 search、 get-property、 get-value、 get-focused、 wait-for |
| ターンを待ちますが、デスクトップを使用することはありません |
set-value、 scroll-into-view、 scroll --direction/--to、 record |
| ターンを待機し、デスクトップを排他的に取得します |
invoke、click、drag、hover、scroll --wheel、touch、pen、focus、send-keys、screenshot |
中央の行は理解する価値のある行です。
set-valueを scroll-into-view し、フォアグラウンドではなく UIA パターンを scroll --direction/--to するため、 ヘッドレス/ロックセッションに対応 し続け、誰もデスクトップを使用できないようにします。 ただし、アプリに表示される内容 は 変更されるため、フィールドを編集したり、他のユーザーのクリックの下からリストをスクロールしたりするのではなく、別のワークフローのターンの後ろで待機します。
1 つのワークフロー内で、他の 共有 作業と重複します。つまり、 record が記録している set-value 呼び出しをキャプチャする方法です。 同じワークフローの以前のDesktopExclusiveコマンド (click、screenshot) は、後のコマンドをブロックするのとまったく同じように、独自のワークフローの前方バリアを無視しないため、クリックとそれに続く変更は、記述した順序で維持されます。
screenshot 常に排他的ターンのキュー。 すべてのキャプチャがデスクトップを妨げるわけではありません。Windowsグラフィックス キャプチャによってキャプチャされた通常の表示ウィンドウでは発生しませんが、最小化されている場合はエンジンによってターゲットが復元され、フレーム キャプチャが使用できない場合やライブ画面が読み取られるときにフォアグラウンドにフォールバック--capture-screen。 これらはキャプチャが進行中の場合にのみ表面化する必要があるため、コマンドは推測するのではなく、正面に向かいます。 複数のウィンドウを合成すると、すべてのウィンドウが 1 つの排他的ターンの下でキャプチャされるため、保存された画像は前後の組み合わせではなく、一貫した 1 つの瞬間になります。 ファイルのエンコードと書き込みは、デスクトップがリリースされた後に行われます。
--capture-screenには、1 つのウィンドウが必要です。 ライブスクリーンキャプチャは、実際に前面にあるものを記録し、可能なウィンドウは1つだけです。-w <hwnd>を使用してウィンドウを明示的に選択すると、そのウィンドウの境界内のピクセル (ダイアログやオーバーレイなど) が 1 つの領域に正確に与えられます。これは、最初に画面を読み取る理由です。-aが複数のトップレベルウィンドウまたは所有ウィンドウと一致する場合、そのような選択はないため、フォアグラウンドと戦うのではなく、何かをキャプチャする前にコマンドがinvalid_argumentsで失敗します。winapp ui list-windows -a <app>実行し、-w <hwnd>で再試行するか、--capture-screenをドロップして、独自の内容からすべてのウィンドウを合成します。
record はターンを共有するため、同じワークフロー入力をキャプチャとインターリーブできます。つまり、アプリを駆動するワークフローを記録する方法です。 2 つの注意事項:
- ワークフロー ID を持たない
recordはワンショット所有者であるため、その間、他のすべてのワークフローがブロックされます。 同時に記録してクリックするには、両方のコマンドに同じWINAPP_UI_WORKFLOW_IDを与えます。 - フレーム キャプチャをサポートしていないホストでは、記録は PrintWindow にフォールバックします。この場合、空のフレームの回復でウィンドウがフォアグラウンドになる可能性があります。 そこにデスクトップは 記録全体 のために保持され、コマンドはその出力でそう言います。同じワークフロー入力でも待機します。
表示されるエラー: invalid_ui_workflow_id (変数が設定されているが空または 256 文字を超える)、 desktop_coordination_unavailable (調整状態は読み取らず、安全に再構築できない、または新しい winappによって書き込まれた)、 queue_capacity_exceeded ( 他 のワークフローから 64 個のコマンドが既に待機しています。制限は、開始したプロセスではなく、ライブの外部待機者をカウントするため、終了または強制終了されたコマンドに属するエントリはスロットを占有しません)。 および独自のワークフローのコマンドは、この制限に対するのではなく、互いにキューに入れ、 ui_turn_busy (独自のワークフローがまだコマンドを実行している間はyield )、 cancelled (待機中は Ctrl + C、終了コード 130)。
ターンを早期にリリースする: winapp ui yield
4 秒の猶予期間は フォールバックです。完了したことを確認できない場合は、デスクトップが予約された状態を維持します。 そう言 える 場合は、 yield 誰もが必要とする恵みを待つ代わりに、すぐにデスクトップを手渡します。
$env:WINAPP_UI_WORKFLOW_ID = [guid]::NewGuid().ToString()
winapp ui invoke File -a notepad
winapp ui click "Save As..." -a notepad
winapp ui set-value txt-filename-a1b2 "notes.txt" -a notepad
winapp ui yield # done — a waiting workflow starts now, not in four seconds
- ワンショット コマンドでは、ワークフロー ID をまったく設定しないでください。 1 つを指定しないと、各コマンドは完了した時点でデスクトップを既に解放しており、何も生成されません。
- 特に他のワークフローが待機している可能性がある場合は、複数ステップのワークフローが完了したときに生成されます。 1 つの高速コマンドのコストがかかり、他のすべてのユーザーから 4 秒のストールが削除されます。
- べき 等です。 2 回、または猶予期間が既に経過した後、成功し、
{ "released": false }報告されます。これはスクリプトの通常の終わりであり、失敗ではありません。 - 別のワークフローのターンが解放されることはありません。 他の誰かがデスクトップを保持している場合、または誰もしない場合、それは no-opです.
- 独自のワークフローにまだコマンドが実行されているかキューに登録されている場合、つまり記録がある場合は、
ui_turn_busyで失敗します。 その下でリリースすると、デスクトップがミッドコマンドから解放されるため、何も解放されず、実行中のコマンドは影響を受けません。 それを待つか、それを停止してから、もう一度生成します。 -
WINAPP_UI_WORKFLOW_IDが必要です。 1 つがないと、invalid_argumentsで失敗します。 - アプリもセレクターも必要ありません。ウィンドウではなく予約が返されるため、アプリが閉じた後も引き続き機能します。
待機中のコマンドは、デスクトップをポーリングするのではなく、誰がデスクトップを解放しても起こされるので、キューは待機中にほとんど何もコストがかかり、ハンドオフはすぐに発生します。 また、各ウェイターは、プロセスが強制終了されたときにデスクトップを回復し、何も発行しない場合に、時々再チェックします。キューの先頭にあるコマンドは 5 秒おきに見え、その背後にあるコマンドは数秒ごとに実行されます。これは、ヘッドが実行する前に実行することはできません。
アプリのターゲット設定
プロセス名別
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 search Seven -a calculator # hosted app: uses the frame window that hosts it
一部のパッケージ アプリ (電卓など) には、独自のウィンドウがありません。別のプロセスがフレームをホストします。 一致したプロセス (名前または PID) に表示されるウィンドウがない場合、 -a はコンテンツをホストするフレームを代わりに使用します。 存在しない場合 (アプリがまだ開始中など)、 -a はプロセスを対象とするため、 wait-for ウィンドウが表示されるまで見続けます。
ウィンドウ のタイトル別
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
Commands
状態
アプリに接続し、接続情報を表示します。
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 # elements you can invoke, click, or set-value; 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
winapp ui get-property Document -p FontWeight -a myapp --json # document formatting
プロパティ名の大文字と小文字は区別されます。 不明な名前は、--jsonの下のinvalid_argumentsで失敗します。プロパティを一覧表示する--propertyは省略します。以下の 6 つのテキスト書式設定属性もすべて含まれます。
wait-for --property では、同じ大文字と小文字が区別される名前が使用され、ポーリングの前に不明な名前が拒否されます。
文書全体のテキストの書式設定
書式設定は、現在の選択範囲やキャレットではなく、要素の TextPattern ドキュメント全体で読み取られます。 読み取りでは、フォーカスや選択範囲は変更されません。
| プロパティ | 均一な値 (文字列として返されます) |
|---|---|
FontWeight |
"400" (標準) や"700" (太字) などの数値の重み |
FontName |
フォント ファミリ名 (例: "Courier New" |
FontSize |
ポイント単位のサイズ (例: "15.5" |
ForegroundColor |
RGB(12,34, 56) の"3678732"など、10 進数Windows COLORREF (0x00BBGGRR) |
IsItalic |
"True" または "False" |
StrikethroughStyle |
"0" (なし) や "1" (単一) などの数値 UIA テキスト装飾スタイル |
数値は、インバリアント書式設定 (ロケールに関係なく小数点) を使用します。 代わりに、各属性は次を返すことができます。
| Value | 意味と次のステップ |
|---|---|
"Mixed" |
書式は文書内で異なります。 均一な値として扱わないでください。このコマンドは、個々のテキスト範囲に対してクエリを実行しません。 |
"NotSupported" |
ドキュメントの TextPattern プロバイダーは、この属性を報告しません。 アプリのアクセシビリティ サポートを確認します。 |
"Unavailable" |
要素に TextPattern がありません。
inspectまたはsearchを使用して、そのテキスト/ドキュメント要素を検索します。 |
すべてのプロパティを一覧表示する場合、キャッシュされた基本プロパティは、ライブ要素を解決できない場合は引き続き使用でき、他のプロパティを破棄せずに形式が正しくない値が省略されます。 これらの省略は警告としてログに記録されます。 省略の代わりにエラーを取得するために、特定の書式設定プロパティを要求します。
プロバイダーのエラーは、 "Unavailable"ではなく、エラーのままです。
stale_elementの場合は、アプリをもう一度検査し、現在のセレクターで再試行します。
JSON エンベロープには、elementId、型指定されたelement、文字列値のpropertiesが含まれます。
BoundingRectangleを含む既存のプロパティは、その形式を保持します。
たとえば、 properties の書式設定部分は次のとおりです。
{
"FontWeight": "700"
}
スクリーンショット
ウィンドウまたは要素を PNG としてキャプチャします。
winapp ui screenshot -a notepad # saves screenshot.png in cwd
winapp ui screenshot -a notepad --output my.png # custom filename
winapp ui screenshot --quiet -a notepad -o my.png # save without informational output
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 -w 131906 --capture-screen # one screen region, with visible overlays in place; foregrounds window
winapp ui screenshot -a myapp --focus # bring window to foreground first, then capture (default WGC path)
要素セレクターがない場合、既定のキャプチャでは、複数のウィンドウが、個別のファイルではなく 、1 つのラベル付きの 1 つの複合 PNG に結合されます。
-a プロセス名または PID によって、アプリのウィンドウとその所有ウィンドウが含まれます。 タイトルベースの -a 一致では、1 つの一致するウィンドウとその所有ウィンドウが選択されます。 -w プロセス内のすべてのウィンドウではなく、1 つのウィンドウと独自のウィンドウを明示的に選択します。 したがって、メイン HWND を明示的に選択した場合でも、所有するダイアログまたはツールヒントは独自のパネルとして表示されます。 要素セレクターは、ウィンドウを作成するのではなく、その要素にトリミングします。 独自のポップアップ ウィンドウで開くメニュー、ポップアップ、ヒント、または教育ヒントの要素は、その背後にあるウィンドウからではなく、そのポップアップからトリミングされます。
--quiet では、保存されたパスを含め、単一ウィンドウキャプチャと複合キャプチャの両方の情報出力が抑制されます。 警告とキャプチャ失敗の診断は引き続き表示されます。 ファイル パスとディメンションを構造化された出力として必要な場合は、代わりに --json を使用します。
--on sandboxでは、ホストの宛先--output名前を付けます。 プレーン出力が成功し、イメージの配信後にそのホスト パスを報告 --json 。
既定のキャプチャ パスでは、Windowsが使用されます。Graphics.Capture (WGC) は、実際の DWM 複合サーフェスを読み取り、丸い角、透明度を維持し、ウィンドウが他のwindowsによって隠されている間も動作します。 WGC が使用できない (以前のWindows ビルド) 場合、CLI は PrintWindow にフォールバックします。
--capture-screen -w <hwnd>は、ターゲット ウィンドウが所有していないオーバーレイなど、画面上の位置に表示されるポップアップまたはヒントが必要な場合に使用します。 ラベル付きパネルを作成するのではなく、そのウィンドウの画面領域を読み取り、最初にウィンドウをフォアグラウンドにします。
-aでは、一致するウィンドウが 1 つだけ必要です。最上位または所有の複数のウィンドウが一致する場合は、winapp ui list-windows -a <app>を使用し、-w <hwnd>で再試行します。 キャプチャ モードを切り替えずにウィンドウをフォアグラウンドするだけの場合は、 --focus を使用します (たとえば、スクリーンショットがユーザーが現在見ている内容と一致していることを確認します)。
画面 DC は実際に前面にあるものをキャプチャするため、
--capture-screenターゲットがキャプチャする直前にフォアグラウンドに到達したことを確認 し、キャプチャしなかった場合はforeground_not_targetで失敗します (フォーカス盗難防止、UAC プロンプト、または別のウィンドウ自体がアクティブ化されます)。 その場合、画像は書き込まれず、以前はコマンドが 0 を終了し、間違ったウィンドウの画像が返されました。ui record --capture-screenは、最初のフレームの前に同じチェックを適用します。
レコード
ウィンドウまたは要素領域を H.264 MP4 に記録します。 無人スクリプトには肯定的な --duration-sec を使用します。 継続時間がない場合、記録は Ctrl + C キーを押すか、リダイレクトされた stdin の場合は改行または EOF まで続行されます。 npm uiRecord および targetRecord ヘルパーには、1 から 86400 までの整数 durationSec が必要です。中止信号は、録音を正常に終了するのではなく、強制的にキャンセルします。
# Record for 10 seconds
winapp ui record -a myapp --duration-sec 10 --fps 15 --output demo.mp4
# Add agent-readable frames
winapp ui record -a myapp --frames --duration-sec 10 --fps 10 --output evidence.mp4 --json
# Stop an unbounded recording through stdin
"" | winapp ui record -a myapp --json --output capture.mp4
# Include screen overlays and popups
winapp ui record -a myapp --capture-screen --duration-sec 5 --output with-popups.mp4
オプション:
-
--duration-sec N— N 秒間の記録。 停止するまでの既定の 0 レコード。 -
--fps N— 1 秒あたりのターゲット フレーム数 (既定値は 15)。 -
--max-edge N— 最も長いエッジが最大 N ピクセルになるようにダウンスケールします (0 = ダウンスケールなし)。 -
--capture-screen— 画面 DC からキャプチャします (オーバーレイ/ポップアップが含まれます。ウィンドウの前景)。 -
--output <path>— 出力 MP4 パス。 既定値はrecording-<timestamp>-<guid>.mp4です。 -
--overwrite— 新しいテイクが完了した後、既存の記録出力を置き換えます。 これを指定しないと、既存の出力は拒否されます。 -
--frames— タイムスタンプ付き JPEG 証拠を<output-name>.framesに書き込みます。 1 から 30 fps、--max-edge64 から 4096 (既定値は 1280) をサポートします。 フレーム データの上限は 1 GiB です。上限に達した場合、MP4 は続行されます。
エージェントが読み取り可能なフレーム成果物:
evidence.mp4
evidence.frames/
manifest.json
frames.ndjson
frames/
frame-000000-t000000000012.jpg
frames.ndjson には、 sampleIndex、単調 elapsedMs、MP4 相対 mediaTimeMs、 imageIndex、 file、および changedを含むサンプルごとに 1 行があります。 連続するピクセル同一サンプルでは、前の quality-85 JPEG が再利用されます。
manifest.json は、要求、タイミング、MP4 の状態、画像のサイズ、および状態 (complete、 partial、または truncated) を記録します。 切り捨てられたタイミングは保持されたプレフィックスをカバーし、 video は完全な MP4 を記述します。
記録を --overwriteに置き換える場合を除き、新しい出力パスを選択します。
これを使用しない場合、既存のビデオまたはそのペアの .frames ディレクトリは、 --framesを省略した場合でも記録をブロックします。
新しいキャプチャが失敗した場合、前の MP4 はそのまま残ります。 置換が成功すると、新しい記録で--framesが省略された場合でも、前のフレーム ディレクトリは<output-name>.frames.previous-<id>として保持されます。 再試行する前に、部分的な証拠を保持し、報告された recoveryHint に従います。 MP4 の最終処理が失敗した場合は、保持されたフレームを <output-name>.frames.partial-*で発行できます。 フレームアーティファクトには暗号化されていない画面コンテンツが含まれています。スクリーンショットやビデオのようにそれらを処理します。
--on sandboxでは、MP4 とフレーム ディレクトリの両方がホストに配信されます。これには、--outputを省略した場合の既定の出力も含まれます。 中断された記録とデスクトップ全体のキャプチャについては、「 サンドボックス キャプチャ」を参照してください。
キャプチャ モード (JSON mode フィールドで報告):
-
wgc— Windowsグラフィックス キャプチャ (既定では、ウィンドウが隠れている間に機能します)。 -
printwindowGDI PrintWindow (このシステム/セッションで WGC が使用できない場合はフォールバックします。代わりに画面 DC を使用するには、--capture-screenを使用して再実行します)。 -
screen—--capture-screenを介して画面 DC を表示します (オーバーレイ/ポップアップが含まれます。ウィンドウが前面に表示されます)。
JSON 出力 (--json):
-
stdout: ケイデンス、停止理由、省略可能な
frameArtifacts、警告など、最終的な記録結果。 -
stderr: 1 行に 1 つの JSON オブジェクト:最初のフレームの後に
recording-startedイベントが発生し、後で記録が失敗した場合はエラーが続きます。 フレーム パスは、フレーム出力がアクティブな場合にのみ含まれます。
エラー コード:
-
element_not_found— セレクターが一致しませんでした。 -
ambiguous_selector— セレクターは複数の要素に一致しました。推奨されるナメクジを使用してください。 -
invalid_arguments— オプション値が無効です。 -
output_exists— 記録出力は既に存在し、要求されたオプションでは置き換えることができません。 -
frame_output_failed— フレーム出力が失敗した後も、どちらのアーティファクトも保持できません。 -
partial_output— 完了したアーティファクトは 1 つだけです。partialOutputとrecoveryHintを検査します。
要素セレクターは、描画されるウィンドウからその要素の領域を記録します。 独自のポップアップ ウィンドウで開くメニュー、ポップアップ、ヒント、または教育ヒントの項目の場合、記録には、その背後にあるウィンドウではなくポップアップが表示されます。
呼び出す
winapp ui invoke SettingsCategory -a myapp --action select
winapp ui invoke AgreeCheckbox -a myapp --action toggle-on --json
winapp ui invoke SizeComboBox -a myapp --action expand
winapp ui invoke Open -w <dialog-HWND> --root Actions --type Button --class-name Button --action invoke
winapp ui invoke SubmitButton -a myapp
テストで選択した要素に対して特定の操作を実行する必要がある場合は、 --action を使用します。 要求されたアクションが失敗した場合でも、別のパターンや呼び出し可能な先祖を試すことはありません。 呼び出しと選択の両方をサポートするコントロールは、 --action selectで呼び出されずに選択されます。
--actionでは、slug は 1 つの要素をターゲットとします。複数の要素に一致するプレーンテキストまたは AutomationId セレクターは、最初の一致ではなく 0 以外の終了コードで閉じられ失敗するため、名前があいまいな場合はinspect/searchからスラッグを渡します。
--root、--type、および--class-name--actionの有無に関するクエリで説明されているように、一致を絞り込みます。
-w <dialog-HWND>を使用してアクションをそのダイアログに制限するか、アプリのウィンドウを含める-a <app>します。 フィルター処理された呼び出しは、動作する前に一意のターゲットを確認し、一致する要素を 1 つだけ必要とし、別のウィンドウや呼び出し可能な先祖に切り替えることはありません。
element_not_foundでは 0 個の一致が失敗し、重複はambiguous_selectorで失敗します。 古い要素またはリサイクルされたウィンドウは、動作せずに失敗します。 inspect または search を再実行し、現在のセレクターを選択します。
--actionしない場合でも、フィルター処理された呼び出しでは、その 1 つの要素に対して順番にパターンが試行されます。
| アクション | Operation |
|---|---|
invoke |
InvokePattern.Invoke |
select |
SelectionItemPattern.Select |
toggle |
TogglePattern.Toggle、1 回だけ |
toggle-on / toggle-off |
ToggleState の読み取り。は、既に正しい状態を変更せずに成功します。それ以外の場合は、切り替えて確認します |
expand / collapse |
ExpandCollapsePattern.Expand / Collapse |
toggle-onとtoggle-offの場合、開始Indeterminate状態では、最大で 2 つの遷移が許可され、それぞれの後の状態を確認できます。 その他の開始状態では、1 つの遷移が許可されます。 要求された状態に達しなかった場合、切り替えを続けるのではなく、コマンドは失敗します。 検証に失敗すると、コントロールを変更したままにすることができます。次に何をすべきかを決定する前に、 ToggleState を読んでください。
--actionおよびフィルターを使用しない場合、自動動作は変更されません。InvokePattern、TogglePattern、SelectionItemPattern、ExpandCollapsePattern (expand) を試し、必要に応じて呼び出し可能な先祖の再試行を行います。
サポートされていないアクションは、0 以外の終了コードで失敗し、 --jsonでは stderr で構造化エラーが発生します。 選択したコントロールを調べて、サポートするアクションを選択するか、目的の親を明示的にターゲットにします。 成功 JSON には、 requestedAction と performedActionが含まれています。 JSON リファレンスを参照してください。
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
他の入力挿入動詞と同様に、
clickはターゲットをフォアグラウンドに移動し、間違ったウィンドウをクリックするのではなく、 高速で失敗 します (ロック/セキュリティで保護されたデスクトップでno_interactive_desktop、フォーカスを転送できない場合はforeground_not_target)。 また、 ボタンダウンの直前に要素が再解決されます。カーソルを配置した後、最終的な位置チェックが 1 回行われるので、クリックが空の領域に移動した後に成功を報告する代わりに、継続的に移動/アニメーション化するターゲットがtarget_movedで失敗します。報告された成功は、ボタンがダウンしたときにターゲットがまだ配置されていることを意味します。
ドラッグ
ある時点でマウス ボタンを押し、別のポイントに移動してから、drag <from> <to>で離します。ここで、各エンドポイントは要素セレクター (要素の中心にドラッグ)、または画面座標x,ywinapp ui inspectによって報告されたとおりに正確に行われます。 自由にミックスして一致させます (セレクター→セレクター、セレクター→コード、coords→coords)。
中間移動で SendInput を使用して、アプリで WM_MOUSEMOVE メッセージの現実的なストリームを表示します。 ハンドルの並べ替え/サイズ変更、スライダー、キャンバス描画、ドラッグ アンド ドロップに使用します。
winapp ui drag itm-card-9f8e itm-slot-2c1a -a myapp # reorder: card center → slot center
winapp ui drag itm-card-9f8e 300,400 -a myapp # element center → screen coords (from inspect)
winapp ui drag 120,200 480,200 -a myapp # raw screen coords → screen coords
winapp ui drag itm-card-9f8e itm-trash-0001 -a myapp --right # right-button drag
# Press-and-hold / long-press and drop-target dwell
winapp ui drag tile-photo-7b3c tile-photo-7b3c -a myapp --hold-ms 600 # long-press: from == to, hold 600ms, no move
winapp ui drag itm-card-9f8e pane-left-2c1a -a myapp --dwell-ms 350 # settle on the drop target before releasing
オプション:
-
--right— 左ボタンではなく、マウスの右ボタンでドラッグします。 -
--hold-ms <ms>— 移動する前に、ボタンを下に押したままにします (既定値: 0)。<from> == <to>(動きなし) を使用すると、長押し/長押しジェスチャが実行されます。 -
--dwell-ms <ms>— 移動後、解放する前に目的地に住みます (既定値: 0)。 ボタンアップの前に(カーソルが到着した瞬間ではなく)持続的なホバーからラッチする ターゲット/マージオーバーレイをドロップ できます。
ベア
x,yは、レポートwinapp ui inspect/search同じ空間内の画面座標であり、セレクターは要素の中心に解決されます。最初にポイントを選択するために検査します。
send-keys --via send-inputと同様に、dragはターゲットをフォアグラウンドに移行した後、画面座標で OS 全体を挿入します。 ターゲットにフォーカスを移動できない場合 (たとえば、バックグラウンド プロセスからフォーカスを盗む防止)、間違ったウィンドウをドラッグしたり、最初にウィンドウをクリックしたりするのではなく、コマンドが 失敗 (foreground_not_target) します。 ロック/セキュリティで保護されたデスクトップでは、no_interactive_desktopで失敗します。 各要素エンドポイントは、 ドラッグの直前に再解決されます。移動/サイズ変更中 (アニメーション化対象) の場合、コマンドは古いポイントにドラッグするのではなく、target_movedで失敗します。 (ベアx,yエンドポイントは再検証できないため、as-is使用されます)。
タッチ
Windows ポインター挿入 API を使用して合成タッチ ジェスチャを挿入します。 コンタクト アンカーは、要素セレクター (要素の中央を使用) か、x,yを介した明示的な--at (同じ空間winapp ui inspectレポート) のいずれかです。 マウス シミュレーションでは表現できないタップ/プレス操作やマルチタッチ ジェスチャに使用します。
winapp ui touch btn-ok-1a2b -a myapp # tap at the element center
winapp ui touch -a myapp --at 320,240 # tap at explicit screen coords
winapp ui touch tile-photo-7b3c -a myapp --gesture long-press --hold-ms 600
winapp ui touch -a myapp --at 100,300 --gesture swipe --to-point 400,300
winapp ui touch img-map-9f8e -a myapp --gesture pinch --distance 200 # pinch-to-zoom out (2 fingers)
winapp ui touch img-map-9f8e -a myapp --gesture stretch --distance 200 # stretch-to-zoom in (2 fingers)
オプション:
-
--gesture <g>—tap(既定)、double-tap、long-press、swipe、pinch、stretch。 -
--at <x,y>— 明示的な開始点 (画面座標)。 既定値はセレクターの要素の中心です。 -
--to-point <x,y>—swipeの終点。--directionよりも優先されます。 -
--direction <right|left|up|down>— スワイプ方向 (既定値:right)。--distanceと組み合わせて、--to-pointが指定されていない場合にエンドポイントを計算します。 -
--distance <px>—pinch/stretchの指の広がり、またはピクセル単位でスワイプします。 -
--hold-ms <ms>— 持ち上げる前に連絡先を押したままにします (長押しホールド時間。設定されていない場合、long-pressの既定値は 500 ミリ秒です)。 -
--duration-ms <ms>— 移動ジェスチャのグライド時間 (スワイプ/ピンチ/ストレッチ、既定の 300)。 -
--fingers <n>— 連絡先の数 (1 ~ 10、既定値は 1)。pinch/stretch常に 2 を使用します。
注入の安全。
touchは、ゼロ以外のターゲット ウィンドウ ハンドルが解決され、そのウィンドウがフォアグラウンドを保持しない限り、挿入を拒否します。ウィンドウを解決できない場合、フォーカスを転送できない場合はno_target、ロック/セキュリティで保護されたデスクトップでforeground_not_targetすると、no_interactive_desktopで失敗します。 すべての座標 (要素の中心、明示的な--at/--to-point、および生成されたウェイポイント) は、ターゲット ウィンドウの四角形に対してチェックされます。ウィンドウの外側のポイントは致命的でない警告 (warnings[]の--jsonエントリ、またはテキスト モードの警告行) として表示され、挿入が続行されます。マウス動詞 (click/drag/hover/scroll) と一致します。これは、ウィンドウ外の座標にも挿入されます。--fingers10 を超えた場合は、前もって拒否されます。ハードウェアノート。 タッチは最新の合成ポインター デバイス (
CreateSyntheticPointerDevice(PT_TOUCH)) を優先し、レガシInitializeTouchInjection/InjectTouchInputAPI にフォールバックします。 現在のデバイス/セッションでインジェクションがサポートされていない場合、コマンドは、誤った成功を報告するのではなく、 実際の Win32 エラー コード (例: "unsupported") を表示します。ゼロ以外の終了は "touch not delivered" として扱われます。リモート デスクトップ/VM セッション。 リモート デスクトップ (RDP) または一部の VM セッションでは、OS が実際にターゲット アプリに到達することなく合成タッチ (終了 0) を受け入れる場合があります。 リモート セッションが検出されると、
touchは配信の不確定性に関する警告 (warnings[]の--jsonエントリ、またはテキスト モードの警告行) を追加します。 ✅/終了 0 は、アプリが入力を受け取ったのではなく、インジェクション呼び出しが成功したことを意味します。重要な場合は、ui screenshot/ui inspectで効果を確認します。
ペン
Windows合成ポインター API (; を使用して、合成CreateSyntheticPointerDevice(PT_PEN)入力 (タップとインク ストローク) を挿入します。Windows 10 1809 以降)。 要素の中心、明示的な --at ポイント、または完全な --path インク ストロークをターゲットにします。
winapp ui pen canvas-1a2b -a myapp # pen tap at the element center
winapp ui pen -a myapp --at 320,240 --pressure 0.8 # firm pen tap at explicit coords
winapp ui pen -a myapp --path "100,100 150,120 210,140 260,120" # draw an ink stroke
winapp ui pen -a myapp --path "100,100 260,100" --eraser # erase along a stroke
winapp ui pen -a myapp --at 200,200 --tilt-x 30 --tilt-y -15 # tilted pen contact
オプション:
-
--at <x,y>ペンの接触ポイント (画面座標)。 既定値はセレクターの要素の中心です。--pathが指定されている場合は無視されます。 -
--path "<x,y x,y …>"— 空白で区切られたx,yペアとしてのインク ストローク パス (1 ポイント パスはタップ)。 -
--pressure <0.0–1.0>— 筆圧 (既定値は 0.5)。 -
--tilt-x <deg>/--tilt-y <deg>— ペンの傾き角度、-90 から 90 (既定値は 0)。 -
--eraser— ペン先ではなくペンの消しゴムの端を使用します。 -
--duration-ms <ms>— パス全体に補間された UPDATE フレームとして分散されたストローク移動時間の合計 (ミリ秒単位): ウェイポイントあたり最大 10 ミリ秒。 これを使用して、ペンが最初から最後まで目に見えて動く速度を制御します。
注入の安全。
touchと同様に、penはゼロ以外の前景のターゲット ウィンドウ (no_target/foreground_not_target/no_interactive_desktop) なしで挿入することを拒否し、すべてのインク ポイントをターゲット ウィンドウの四角形に対してチェックし、マウス動詞と一致しながら、ウィンドウ外座標を致命的でない警告 (warnings[]で--json、またはテキスト モードの警告行) として表示します。 無効な--pressure(0.0 ~ 1.0 外) または傾き (±90° の外側) は、前もって拒否されます。リモート デスクトップ/VM セッション。 ペン のルーティングは、特にリモート デスクトップよりも信頼性が低くなります。インジェクション呼び出しは成功 (終了 0) を報告できますが、ペン入力はアプリに到達しません。 リモート セッションが検出されると、
penは配信の不確定性の警告 (warnings[]では--json、テキスト モードでは警告行) を追加するため、✅は確認された配信と間違われません。 ローカルの対話型デスクトップでペン依存フローを検証します。
ホバー
マウスを要素の中央に移動して、ホバー効果 (ヒント、ポップアップ、表示状態) をトリガーします。 小さなウィグルで現実的なマウスの動きに SendInput を使用し、構成可能なドウェル時間を待ちます。
winapp ui hover btn-info-a1b2 -a myapp # hover with default 800ms dwell
winapp ui hover btn-info-a1b2 -a myapp --dwell-time 1200 # longer dwell for slow tooltips
winapp ui list-windows -a myapp # use the main window's HWND below
winapp ui hover btn-info-a1b2 -a myapp; winapp ui screenshot -w <hwnd> --capture-screen # hover then capture tooltip in place
オプション:
-
--dwell-time <ms>— 効果が表示されるまでホバーした後に待機する時間 (既定値: 800、範囲: 0 ~ 10000)
send-keys
合成キーボード入力 ( clickに対応するキーボード) を送信します。 UIA にはキーボードインジェクション パターンがないため、Win32 レイヤーにドロップします。 キーボード ナビゲーション (矢印、Tab、Enter、Esc)、ショートカット (ctrl+c、 alt+f4)、および set-valueのアトミック書き込みではなく、キーストロークごとのイベントを必要とするコントロールへの入力に使用します。
winapp ui send-keys "down down enter" -a myapp # arrow navigation then commit
winapp ui send-keys "ctrl+a delete" -a myapp # select all, then delete
winapp ui send-keys "Hello world" --target txt-name-a1b2 -a myapp # focus a field, then type text
winapp ui send-keys "text=down text=down text=enter" -a myapp # type the words, don't press the keys
winapp ui send-keys "down down enter" -a myapp --verbatim # same, but type the whole argument literally
winapp ui send-keys "alt+f4" -a myapp # close window via accelerator
winapp ui send-keys "vk=0x5D" -a myapp # a key with no friendly name (Apps/Menu key)
winapp ui send-keys "ctrl+shift+t" -a myapp --via send-input # use OS-wide injection instead of PostMessage
winapp ui send-keys "win+shift+v" -a myapp --via send-input --allow-system-keys # opt in to drive a global hotkey
winapp ui send-keys "ctrl+capslock+f12" -a myapp --via send-input # Narrator command: toggle developer mode
キー文法 (空白で区切られたトークン、複数トークン文字列の引用符):
-
名前付きキー —
enter/return、tab、esc/escape、space、backspace、delete/del、insert、home、endpageup/pgup、pagedown/pgdn、up/down/left/right、f1–f16、apps、printscreen、capslock。 -
シーケンス — 複数のトークンが順番に押
down down enter。 -
修飾子コンボ —
ctrl、shift、alt、win、+:ctrl+shift+t、alt+f4で結合されます。 修飾子で始まるが、最後のセグメント (ctrl+a+b) がエラーになる前に不明なセグメントがあるトークン。text=または--verbatimを使用して入力します。 -
スクリーン リーダー コマンド —
capslockまたはinsert(エイリアスins)、ナレーター、NVDA、JAWS キーを押したままにします。ctrl+capslock+f12、ナレーター開発者モードが切り替わります。 スクリーン リーダーはポストされたキーを受け取らないので、--via send-inputが必要です。 スクリーン リーダーが実行されていない場合は、capslockを押すと Caps Lock のオンとオフが切り替わり、コマンドが警告されます。これを回避するには、insertを押したままにします。 -
リテラル テキスト — 既知のキーではないトークンは、文字によって型指定されます:
hello。 隣接するリテラル単語はそれらの間のスペースを保持するため、"Hello world"のような引用符で囲まれた語句は逐語的に型指定されます (スペースは保持されます)。+やC++などのa+bを含むリテラルはテキストとして型指定され、コンボとして解析されません。 -
明示的なリテラル エスケープ — キーまたは修飾子の名前と競合する場合でも、トークンに
text=を付けて逐語的に入力します。text=enterEnter キーを押す代わりに "enter" という単語を入力し、リテラル文字列text=ctrl+a入力します。vk=エスケープをミラー化します。エスケープされた値は、隣接するリテラル単語 ("下位"text=down low→) と結合されます。 トークンは空白の分割 (および隣接するリテラルは単一のスペースで再結合) であるため、text=値内のバックスラッシュ エスケープを使用して、空白文字を入力します。空白文字は、\s→スペース、\t→ タブ、\n→改行、\r→改行、リテラル バックスラッシュ\\→入力します。\nを\rし、それぞれ 1 つの改行 (Enter/\r\n) を挿入VK_RETURNので、text=line1\nline2とtext=line1\r\nline2両方に 1 つの改行を入力します。 そのため、text=a\s\sbは "a b" (二重スペース) を入力し、text=\shiは先頭のスペースを保持します。 認識されないエスケープ (例:\x) は、そのままです。 -
引数全体リテラル (
--verbatim) — ペイロード全体がリテラル テキストの場合は、すべてのトークンを--verbatimでエスケープするのではなく、text=を渡します。 名前付きキー/コンボ/vk=/text=解釈なしで、指定されたとおりにキー引数全体を入力し、通常のパスとは異なり、\sを必要とせずに正確な内部空白文字 (折りたたみなし) を保持します。 したがって、send-keys "down down enter" --verbatimは単語を入力し、send-keys "a b" --verbatimは二重スペースを保持します。 円記号エスケープは モードではデコード--verbatim(\sは円記号と "s" として型指定されます。エスケープされた制御文字が必要な場合は、text=トークンを使用します。 -
未加工の仮想キー — フレンドリ名のないキーの
vk=0xNN(16 進数) またはvk=NN(10 進数) です。
オプション:
-
--target <selector>— キーを送信する前に、この要素に (UIA 経由で) フォーカスします。 これを指定しないと、キーはアプリの現在フォーカスされている要素に移動します。 -
--verbatim— キー引数全体をリテラル テキスト (キー/コンボ/vk=/text=解析なし) として入力し、正確な空白文字を保持します。 トークンごとの引数全体の形式text=エスケープします。 -
--via <transport>—post-message(既定) は、ターゲット ウィンドウのキューにWM_KEYDOWN/WM_KEYUP/WM_CHARを投稿します。 HWND を対象とし、UIPI をバイパスします (整合性レベル間で機能します)。send-inputは、SendInput経由で OS 全体を挿入し、フォアグラウンド ウィンドウに移動します。
トランスポート/既知の制限の選択:
-
post-messageは、UIPI をバイパスし、フォアグラウンドのウィンドウに依存しないため、既定値です。 制限:WH_KEYBOARD_LL低レベルのフック (任意のウィンドウ キューの上流にあるタップ入力) を介して登録されたグローバル ホットキーをトリガーすることはできません。また、GetAsyncKeyStateを介して生のキー状態を読み取るアプリは、保持されている修飾子を観察できない可能性があります。 フォアグラウンド後にターゲット スレッドの フォーカスされた子ウィンドウ (GetGUIThreadInfo経由) が自動的に解決され、投稿されるため、コントロールが別の子ウィンドウである従来の Win32/WinForms アプリは、コントロールを手動でターゲットにすることなくキーを受け取ります。 WinUI 3/UWP アプリには、子 HWND のないウィンドウなしの XAML コントロールがあるため、投稿されたWM_CHAR/WM_KEYDOWNは何も受信せず、ドロップされます。ポストメッセージでそれらを駆動することはできません (コマンドの警告と終了 0)。--via send-inputを使用します。 (WPFウィンドウは単一 HWND であり、内部的にフォーカスされた要素にキーをルーティングするため、事後メッセージはそこで機能します)。 -
send-inputは完全に実際の入力 (GetAsyncKeyStateに表示される修飾子、低レベルのフックを発生させます) を生成しますが、 昇格されたプロセスから低整合性 (AppContainer/AppX) ターゲットに挿入すると、フォアグラウンドであり、UIPI によってブロックされるウィンドウに移動します。send-inputエラーが報告された場合、ターゲットは昇格または AppX アプリである可能性があります。post-messageを使用するか、一致する整合性レベルで CLI を実行します。 安全ガードとして、send-inputは、フォーカスを移動できなかった場合にforeground_not_target、挿入する直前にターゲット ウィンドウが実際にフォアグラウンドに存在することを確認し、失敗 () します。フォーカスを設定するか、最初にウィンドウをクリックします。 ロックまたはセキュリティで保護されたデスクトップでは、代わりにno_interactive_desktop(挿入するフォアグラウンド ウィンドウが存在しません) で失敗します。セッションのロックを解除するか、UIA パターン動詞 (set-value、invoke) を使用します。 -
システム予約コンボ (
win+l、win+r、ctrl+shift+esc、ctrl+alt+del、alt+tab、alt+f4、ctrl+esc、lonewin/printscreen、...) は、OS 全体で送信されたターゲットではなく、OS/シェルで動作します。send-inputOS レベルで挿入するとターゲット ウィンドウを大きく超える効果があるため (たとえば、invalid_argumentsはセッションをロックするため)、既定ではそれらを拒否します (win+lでエラーが発生し、何も送信されません)。 オプトイン--allow-system-keys渡します。これにより、PowerToys のwin+shift+vやwin+rなどのグローバル ホットキーを駆動できます (グローバル低レベルフックは OS 全体の入力ストリームを監視するため、挿入されたコンボが起動します)。win+l自動化から回復できないLockWorkStation()を介してワークステーションをロックする例外 (CI セッションとリモート デスクトップ セッションが中断されます)、ctrl+alt+delは、フラグに関係なく挿入された入力から削除Windows Secure Attention Sequence (SAS) です。影響を受けることはありません。そのため、誤解を招く成功を報告する代わりにエラー (invalid_arguments、終了 1) が発生します。 他のコンボ (alt+f4、ctrl+shift+esc、win+r、...) はフラグで許可されます。呼び出し元は注意してください。 または、システムコンボを特定のウィンドウに配信するには、ウィンドウスコープで影響を受けない--via post-messageを使用します(ポストされたwin+lは無害ですが、ポストされたalt+f4はまだターゲットウィンドウを閉じます)。
キーストロークごとのイベント (KeyDown/TextChanged):
-
名前付きキーと修飾子コンボ (
down、enter、ctrl+shift+t、vk=0xNN) は、KeyDownのトランスポートで実際のKeyUp(および) を起動します。これらは個別のWM_KEYDOWN/WM_KEYUP(または仮想キー イベントSendInput) として配信されます。 -
リテラル型指定テキスト (
hello) はトランスポートによって異なります。-
--via send-inputは、各文字をアクティブなキーボード レイアウトの仮想キー (+ Shift) にマップするため、ターゲットには正しい仮想キーを持つ正規のKeyDownが表示され、その後に OS で構成されたWM_CHAR(TextChangedを上げる) (つまり、文字ごとに 1 つの完全なキーストローク) が表示されます。 現在のレイアウトで到達できない文字 (または Ctrl/AltGr が必要) は Unicode パケットにフォールバックするため、正確な文字は引き続き到達します。send-inputは、キーストロークごとのKeyDown忠実性が必要な場合に使用します (たとえば、ハンドラーキーがTextBox離れた WinUI 3/WPFKeyDownを駆動する)。 通常の (管理者特権以外の) WinUI 3 テスト ホストの場合は、フォアグラウンド ウィンドウをターゲットwinapp ui focusので、そのウィンドウを最初にフォアグラウンド (send-input/クリック) します。 -
--via post-messageは、文字ごとに 1 つのWM_CHARをポストします (型指定されたテキストのWM_KEYDOWN/はポストWM_KEYUP。これらは名前付きキー/コンボ用に予約されています)。文字単位のは発生KeyDown。 ウィンドウの フォーカスされた子コントロールに自動的に再ターゲットされるため、従来の Win32/WinFormsWM_CHAR駆動型の編集コントロールはテキストを配置します (TextChangedを上げる)。 警告:WinUI 3/UWP/XAML アプリ (winapp のプライマリ ターゲット) には、ポストされたWM_CHAR/を無視するWM_KEYDOWNコントロールがあるため、コマンドが成功を報告しても、リテラル テキストと名前付きキー (Enter、数字、...) は到達しません。 ターゲットが XAML のように見え、まだ 0 を終了すると警告が出力されます (PostMessageは fire-and-forget であり、配信を確認できません)。--via send-inputを使用して WinUI 3/UWP/WPF アプリを駆動します。従来の Win32 コントロール用にpost-messageを予約するか、整合性レベル全体でウィンドウ スコープのみを必要とする場合に予約します。
-
JSON 出力 (--json): 結果の hwnd は、キーが配信された 有効な ウィンドウです。 --via post-message これは、コマンドが再ターゲットされたときに解決 されたフォーカスされた子コントロール (必ずしも最上位レベルの -w/-a/-e ウィンドウではない) であるため、自動化によって入力がどこに配置されたかを正確に確認できます。 その有効なターゲットがウィンドウレス XAML ホストのように見える場合、上記の配信に関する注意事項も warnings[] エントリとして表示されるため (コンソールに示されているのと同じアドバイザリ)、 ✅ 終了 0 は、配信が確認済みであると誤解されません。
set-value
プログラムで編集可能な要素に値を設定します (キーストロークなし、アプリのフォアグラウンドなし)。 フォールバック チェーンを使用します。
- ValuePattern — TextBox、ComboBox、PasswordBox、およびほとんどの編集可能なコントロール。
- RangeValuePattern — 値が数値として解析される場合の数値コントロール (スライダー、ProgressBar)。
-
LegacyIAccessible (
IAccessible::put_accValue) — ValuePattern を公開しない TextPattern のみの 編集コントロールのフォールバック (リッチエディット/Document作成ボックスなど)。 これにより、読み取り/書き込みギャップget-value閉じますが、set-valueは読み取れませんでした。
winapp ui set-value txt-textbox-a4b1 "Hello world" -a notepad
winapp ui set-value sld-volume-b2c3 75 -a myapp
winapp ui set-value doc-compose-9f3a "hello" -a myapp # RichEdit/compose box via LegacyIAccessible
3 つのパターンのいずれも値を設定できない場合、 set-value は最後の手段として send-keys を示す明確なエラーで失敗します。
すべてのリッチ エディターでプログラム セットがサポートされているわけではありません。 LegacyIAccessible フォールバックは、アクセシビリティが
IAccessible::put_accValueを実装するコントロール (ネイティブ Win32 リッチエディット コントロールと Chromium/Electron/WebView2 作成サーフェイス) でのみ機能します。 WinUI 3RichEditBoxとWPFRichTextBoxはプログラムによる値の設定をサポートしていません。設計上、コンテンツは読み取り専用 (テキスト パターン、設定可能な値パターンなし) としてUI オートメーションに公開されるため、set-valueは書き込みできません。send-keys(ロック解除されたフォアグラウンド デスクトップが必要) を使用します。
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 get-value SearchBox -a myapp --json
winapp ui wait-for SearchBox -a myapp --value "" --timeout 5000
空のテキスト フィールドが正常に読み取られた場合、アクセシビリティ ラベルではなく、 "text": ""が返されます。 空白のみのコンテンツも JSON で保持されます。
wait-for --value "" は、空のフィールドと一致します。これは、新しいフィールドであるか、編集後にクリアされたフィールドであるかに関係なく、一致します。 代わりにアクセシビリティ ラベルを読み取るために、 get-property --property Nameを使用します。
フォーカス
winapp ui focus txt-textbox-a4b1 -a notepad
必要に応じ、選択したコントロールのウィンドウをアクティブにし、コントロールにフォーカスを合わせます。
セレクターが必要です。 -a <app> または -w <HWND> を使用してターゲットを選択します。
成功とは、ウィンドウがフォアグラウンドであり、選択したコントロールがコマンドが返される前に HasKeyboardFocus 確認されたことを意味します。 このコマンドは、コントロールがフォーカスを報告するために最大 500 ミリ秒を許可します。フォーカスを取り戻そうとするのではなく、ターゲットが前景を消えたり失ったりすると停止します。 メイン ウィンドウの前にある所有ダイアログでは不十分です。ターゲットの場合は、ダイアログでコントロールを選択します。
このコマンドには、ロック解除された対話型デスクトップが必要であり、Windowsアクティブ化の制限はバイパスされません。
foreground_not_targetで失敗した場合は、目的のウィンドウを手動でアクティブ化し、再試行する前にブロックダイアログを確認します。
focus_not_acquiredの場合は、現在の UI を調べて、フォーカス可能なコントロールを選択します。
stale_elementの場合は、inspectまたはsearchでターゲットを再検出します。
検出コマンドと再試行コマンドでは、同じ --on ターゲットを保持します。
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
# Synthesize real mouse-wheel input over the element (1 = one notch up, -1 = one notch down).
# Use this to test handlers that respond to the wheel directly (zoom, custom scroll) rather than ScrollPattern.
winapp ui scroll img-map-a1b2 --wheel -1 -a myapp
オプション:
-
--direction <up|down|left|right>—ScrollPatternを使用して段階的にスクロールします。 -
--to <top|bottom>—ScrollPattern経由で開始/終了にジャンプします。 -
--wheel <notches>—SendInputを介して要素の中心にマウスホイール入力を合成します。ホイール切り込み (デテント):1= 1 ノッチアップ/アウェー、-1= 1 ノッチダウン/方向、3= 3 切り上げ。 (各切欠きは、WHEEL_DELTA消費する 120 ユニットのWindowsSendInputです。CLI では、切り込みは 120 単位でスケーリングされます)。ScrollPatternをバイパスします。
--direction、--to、および--wheelは相互に排他的であり、正確に 1 つを渡します。--wheelは画面座標で OS 全体の入力を挿入するため、ターゲットを最初にフォアグラウンドに移動し、間違ったウィンドウをスクロールするのではなく、フォーカスを転送できなかった場合は失敗 (foreground_not_target) します。
get-focused
winapp ui get-focused -a myapp
winapp ui get-focused -w <HWND> --json
選択したアプリに現在キーボード フォーカスがある要素を表示します。これには、アプリの所有権が親ウィンドウでのみ使用できるコントロールが含まれます。
-wでは、フォーカスは別のウィンドウや同じプロセス内の所有ポップアップではなく、そのウィンドウに属している必要があります。
-aでは、選択したプロセスの他のウィンドウが含まれます。
ターゲットに属する要素を検証できない場合、JSON 出力は hasFocus:false 。 フォーカスまたはウィンドウ所有権のクエリが失敗した場合、コマンドは 0 以外の値を終了します。 get-focused再試行し、ウィンドウが閉じている場合は list-windows で再検出します。
list-windows
ポップアップやダイアログなど、アプリのすべての表示ウィンドウを一覧表示します。 既定では、サイズが 0 の無題のウィンドウ (非表示のシステム ウィンドウ) は除外されます。
winapp ui list-windows -a imageresizer
winapp ui list-windows -a Terminal
winapp ui list-windows # all windows (no filter)
winapp ui list-windows --show-hidden # include invisible zero-size windows
一時停止させる
このワークフローの UI ターンは、4 秒のアイドル状態の猶予期間を待たずに、早い段階でリリースします。
WINAPP_UI_WORKFLOW_IDが必要です。アプリもセレクターも必要ありません。 「 ターンを早期にリリースする」を参照してください。
winapp ui yield
winapp ui yield --json # {"released": true} — or false when nothing was held
フレームワークのサポート
| フレームワーク | 検査 | 検索 | 呼び出す | set-value | スクリーンショット |
|---|---|---|---|---|---|
| WPF | ✅ 完全なツリー | ✅ すべてのプロパティ | ✅ すべてのパターン | ✅ ¹ | ✅ |
| WinForms | ✅ | ✅ | ✅ | ✅ | ✅ |
| Win32 の |
✅ | ✅ | ✅ | ✅ | ✅ |
| WinUI 3 | ✅ | ✅ | ✅ | ✅ ¹ | ✅ |
| 電子 | ⚠️ Chromium ツリー | ⚠️ 制限あり | ⚠️ 異なる | ⚠️ 異なる | ✅ |
| Flutter | ⚠️ 基本 | ⚠️ 基本 | ❌ 最小限 | ❌ | ✅ |
¹ set-value は、ValuePattern/RangeValuePattern を公開するすべてのコントロールに加えて、アクセシビリティが IAccessible::put_accValue を実装する TextPattern のみの編集コントロール (LegacyIAccessible フォールバック) で動作します。
WinUI 3 RichEditBoxとWPF RichTextBoxは例外であり、読み取り専用のテキスト パターン (設定可能な値パターンなし) のみを公開するため、プログラムでプログラムで設定することはできません。send-keys (対話型デスクトップが必要) を使用して入力します。
独自のコードからエンジンを使用する
winapp ui行う操作はすべてライブラリとして使用できるため、CLI にシェルアウトすることなく、テストまたはツールから同じ自動化を実行できます。
| Package | 追加されるもの |
|---|---|
Microsoft.Windows.SDK.BuildTools.WinApp.UIAutomation |
検査、セレクター、UIA パターンの相互作用、入力挿入、スクリーンショット |
Microsoft.Windows.SDK.BuildTools.WinApp.UIAutomation.Recording |
MP4 へのビデオ録画とフレーム バンドル |
var services = new ServiceCollection().AddLogging().AddWinAppUiAutomation().BuildServiceProvider();
var ui = services.GetRequiredService<IUiAutomation>();
var target = UiTarget.FromWindowHandle(myWindowHandle);
var save = await ui.FindSingleElementAsync(target, new UiSelector { Query = "Save" }, default);
await ui.InvokeAsync(target, save!, default);
決定論的アクションの場合は、 UiInvokeActionを受け取るオーバーロードを使用します。
var selected = await ui.FindSingleElementAsync(
target, new UiSelector { Query = "Save" }, requireUnique: true, default);
if (selected is null) throw new InvalidOperationException("Save was not found.");
UiInvokeActionResult result = await ui.InvokeAsync(target, selected, UiInvokeAction.Invoke, default);
requireUnique: true は、呼び出し可能な一致を選択するのではなく、あいまいなテキストを拒否します。 正確な AutomationId の一致は、名前または AutomationId 部分文字列よりも優先されます。一意の名前でも、AutomationId が共有されているコントロールを選択できます。
アプリ スコープのターゲットの場合、そのチェックでは、そのすべてのアプリ/所有ウィンドウが対象となります。 選択範囲を制限するには、 -w <HWND> (または明示的ウィンドウ ライブラリ ターゲット) を使用します。
CLI アクションの結果と同じ意味でPatternとPerformedActionを返します。
検査または選択によって返された要素を、ランタイム スラッグまたは一意の AutomationId をそのまま使用して渡します。 明示的なアクションでは、名前とコントロールの種類によって再バインドするのではなく、見つからない ID またはあいまいな ID が拒否されます。
スコープ付き読み取りの場合は、 UiSelector.Root を別の UiSelectorに設定し、型名に ControlType し、リテラル プロバイダー クラスに ClassName します。 これらは CLI と同じ クエリ述語 を使用します。 サポートされるルート レベルは 1 つだけです。selector.Root.Rootnullする必要があります。 入れ子になったルートは、ターゲット ウィンドウを参照する前に ArgumentException をスローします。 ルート セレクターを入れ子にするのではなく、一意のルート AutomationId または slug を使用します。
UiControlTypes.GetId(name) は、公式の型名と文書化された 2 つのエイリアスを解決し、無効な名前の 0 を返します。
UiControlTypes.GetName(id) は正規名を返すか、認識されない ID の Unknown(id) します。
JSON から復元された UiElement を GetTextAsync または GetPropertiesAsyncに渡す場合は、その Selector と WindowHandleを維持します。 スラッグセレクターは、元の要素を引き続き識別する必要があります。存在しなくなった場合、これらの読み取りでは、同じ AutomationId または名前を持つ別の要素を選択する代わりに、 UiElementNotFoundException がスローされます。 元のクエリをもう一度実行して、結果を更新します。 スコープ読み取りでは、NULL または以前にキャプチャされた値を返すのではなく、一般的な UIA プロパティゲッターと取得された UIA パターンからのエラーも伝達されます。
記録は個別のパッケージであるため、UI のみを検査してドライブするプロジェクトは SkiaSharp に取り込まれません。 オートメーション パッケージは、net10.0-windowsとnet10.0-windows10.0.19041.0の両方を対象としています。後者では、Windowsグラフィックス キャプチャが追加されます。これにより、screenshotは、隠れたwindowsまたは GPU 複合windowsをキャプチャできます。 完全な API とターゲット フレームワークのトレードオフについては、NuGet の各パッケージの README を参照してください。
UiTarget.FromWindowHandleは、既にウィンドウを渡すテスト フレームワークのエントリ ポイントです。たとえば、MSTest.Windows.UIAutomation。そのWindowTest.MainWindowは、MainWindow.Current.NativeWindowHandleと橋渡しする UIA2 AutomationElementです。
Troubleshooting
| エラー | 原因 | ソリューション |
|---|---|---|
| "実行中のアプリが見つかりません" | アプリが実行されていないか、名前の不一致 | プロセス名を確認するか、PID を使用する |
| "複数のウィンドウの一致" | あいまいな -a 値 |
表示されているオプションの -w <HWND> を使用する |
| "複数のウィンドウがある" | プロセスに複数のウィンドウがある |
-w <HWND>を使用して特定のターゲットを設定する |
| "セレクターが一致した N 個の要素" | あいまいなレガシ セレクター |
inspect出力からスラッグを使用するか、レガシ セレクターに[0][1]を追加する |
| "要素が変更された可能性があります" | Slug ハッシュが現在の要素と一致しない |
inspectまたはsearchを再実行して新鮮なナメクジを取得する |
| "どの呼び出しパターンもサポートしていません" | 要素を呼び出すことはできません | 要素で inspect を使用して、呼び出し可能な子を検索する |
| "UIA ウィンドウが見つかりません" | UIA でプロセスが表示されない |
list-windowsを使用して HWND を検索し、次に-w |
| "Window has zero size" | ウィンドウが最小化されている | アプリは自動的に復元されます |
| スクリーンショットにないポップアップ/ドロップダウン | 既定のキャプチャはウィンドウごとであり、未所有のオーバーレイは含まれません | スクリーンショットの オーバーレイ ワークフロー に従って、次のウィンドウを選択します。 -w <hwnd> --capture-screen |
foreground_not_target から --capture-screen |
Windowsアクティブ化を拒否したので、画面キャプチャでは、実際に前面にあるウィンドウが記録されます | ターゲット ウィンドウをクリックするか、フォーカスを盗むウィンドウを閉じて再試行するか、ドロップします --capture-screen |
element_not_found レコード中 |
セレクターが指定されているが、一致する要素がない |
inspectまたはsearchを再実行して新しいセレクターを取得する |
| 記録中に WGC を使用できない | WGC キャプチャの初期化に失敗しました。サイレント フォールバックなし | GPU/ドライバーを確認します。 --capture-screen を使用して画面 DC キャプチャに同意する |
一般的なパターン
移動して確認する
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 list-windows -a myapp # use the main window's HWND below
winapp ui set-value txt-searchbox-e5f6 "query" -a myapp; winapp ui screenshot -w <hwnd> --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 を使用します。
searchモードでのwait-forおよび--jsonの終了コード コントラクト: 要素が一致しない (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)" }
# Read typed element state while preserving the legacy string property map
$property = winapp ui get-property "Counter Display" -a $pid --json | ConvertFrom-Json
if ($property.element.type -ne "Text") { throw "Unexpected type: $($property.element.type)" }
if ($property.element.isOffscreen) { throw "Counter is offscreen" }
JSON エンベロープは次のとおりです。
-
inspect:{ "depth", "interactive", "hideDisabled", "hideOffscreen", "windows": [...] } -
search:{ "matchCount", "hasMore", "matches": [...] } -
wait-for:{ "found", "waitedMs", "element"?, "timedOut" } -
get-property:{ "elementId", "element", "properties": { ... } }
型指定された要素は、 type と数値の x、 y、 width、および heightを使用します。
ジオメトリは物理画面ピクセル単位です。
0,0,0,0は、このプロジェクションUI オートメーション空または表示されない UI 四角形です。isOffscreenは独立しているため、オフスクリーン要素には 0 以外の境界を引き続き含めることができます。
各 inspect --jsonwindows[] エントリと status --json 結果には、 windowDpi、 scale (windowDpi / 96)、 dpiAwareness、および coordinateSpace: "physical-screen-pixels"が含まれます。 ここでは、無条件モニター DPI ではなく、ターゲット ウィンドウの DPI コンテキストについて説明します。Windowsは、非認識ウィンドウの場合は 96、システム対応ウィンドウの場合はシステム DPI、モニターごとのウィンドウでは現在のモニター DPI を報告します。 HWND または DPI コンテキストを読み取ることができない場合、コマンドは 96 を自動的に置き換えるのではなく失敗します。
statusが最上位のウィンドウを持つ前にプロセスを解決すると、hwndは0され、ウィンドウが存在するまで DPI フィールドは省略されます。 プロセス全体の inspectの場合、選択したターゲット ウィンドウは高速のままです。ツリーの読み取り後に後のポップアップが消えた場合、その windows[] エントリは dpiError を保持し、残りのウィンドウ ツリーが返されている間は DPI フィールドを省略します。
各封筒の完全な例については、出荷された winapp-ui-automation スキルの references/ui-json-envelope.md を参照してください。
完全スモーク テストの例
# 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