Skip to main content

windows-app-automation

Windows デスクトップアプリ(Win32・WPF・WinForms・UWP・メモ帳・タスクマネージャーなど)の GUI 自動化・UIテストスキル。「Windows アプリを自動化して」「デスクトップアプリをテストして」「ファイルダイアログを操作して」「Excelを自動操作して」などで発動。pywinauto/winauto 使用。Copilot・Kiro・WSL 対応。

Source facts

Repository
ynitto/sandbox
Last source activity
September 19, 2026 at 00:47
Detected SKILL.md language
Japanese
Stars
1
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
10 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
windows-app-automation
description
Windows デスクトップアプリ(Win32・WPF・WinForms・UWP・メモ帳・タスクマネージャーなど)の GUI 自動化・UIテストスキル。「Windows アプリを自動化して」「デスクトップアプリをテストして」「ファイルダイアログを操作して」「Excelを自動操作して」などで発動。pywinauto/winauto 使用。Copilot・Kiro・WSL 対応。
metadata
{"version":"1.2.0","tier":"experimental","category":"implementation","tags":["windows","native-app","pywinauto","ui-automation","win32","wpf","winforms","desktop-automation","e2e-testing","wsl","copilot","kiro","cross-agent"]}
# windows-app-automation Windows ネイティブアプリを自動化するときは、Python + pywinauto で自動化スクリプトを作成する。 ## 対応エージェント環境 | 環境 | 実行場所 | winauto コマンド | |------|---------|----------------| | **Claude Code** (Windows) | PowerShell / CMD ターミナル | `winauto` または `python winauto.py` | | **GitHub Copilot** (VS Code) | VS Code 統合ターミナル(PowerShell) | `winauto` または `python winauto.py` | | **Kiro** (AWS IDE) | Kiro 統合ターミナル(PowerShell) | `winauto` または `python winauto.py` | | **WSL** (WSL2 端末) | bash/zsh from VS Code / Kiro / Windows Terminal | `winauto`(ラッパー経由で Windows Python を呼ぶ) | > **注意**: pywinauto は Windows 専用。WSL から呼ぶ場合は Windows 側 Python で実行される。 --- ## セットアップ(初回のみ) ### Windows ネイティブ(Claude Code / Copilot / Kiro 共通) ```powershell # 依存ライブラリと winauto コマンドのインストール python tools/winauto/install.py # インストール確認(doctor が pywinauto・デスクトップ到達性・ロック状態を確認する) winauto doctor winauto apps ``` ### WSL 端末から使う場合 ```bash # Windows 側 Python を自動検出してインストール python tools/winauto/install.py # インストール確認(新しい端末で)。doctor は WSL→Windows のブリッジを # 端から端まで確認する: interop → ラッパー → Windows Python → デスクトップ到達性 winauto doctor winauto apps ``` `winauto doctor` は **WSL 側でも Windows 側でも動く唯一のコマンド**で、WSL から実行すると ラッパー越しに Windows 側の doctor を呼び出して所見を合流させる。`--output json` で機械可読。 問題があれば終了コード 1 を返すので、セットアップスクリプトからも判定に使える。 インストーラーが Windows 側 Python を見つけられない場合: ```bash # Windows Python のパスを確認 cmd.exe /c where python # 手動で Windows 側に pip インストール cmd.exe /c python -m pip install pywinauto Pillow pywin32 comtypes ``` ### 依存ライブラリのみインストール(既存 Python 環境に追記) ```powershell pip install pywinauto>=0.6.9 Pillow>=9.0.0 pywin32>=306 comtypes>=1.4.0 ``` --- ## 環境別の実行方法 ### Claude Code / GitHub Copilot / Kiro(Windows ターミナル) これらはすべて Windows 上で動作するため、同じコマンドが使える。 ```powershell # winauto CLI(インストール済みなら直接呼べる) winauto apps winauto tree --app notepad winauto click "name:=OK" --app notepad # またはリポジトリから直接 python tools/winauto/winauto.py apps python tools/winauto/winauto.py tree --app notepad # ヘルパースクリプトも同様 python .github/skills/windows-app-automation/scripts/element_inspector.py --list ``` **Copilot(VS Code)固有の注意点:** - VS Code のターミナルが PowerShell の場合、`python` コマンドが正しく通るか確認する - `python --version` で Python 3.9 以上が表示されることを確認する **Kiro IDE 固有の注意点:** - Kiro の統合ターミナルから実行する(PowerShell) - Kiro エージェントは直接 `!winauto tree --app notepad` のようにシェルコマンドを呼べる - スキルの自動化スクリプトを Kiro に書かせた後、Kiro のターミナルで実行する ### WSL 端末(VS Code Remote / Kiro WSL / Windows Terminal) ```bash # winauto ラッパー経由(インストール済みなら直接呼べる) winauto apps winauto tree --app notepad # パスは WSL パス形式で指定可能(ラッパーが wslpath 変換を行う) winauto screenshot --app notepad --output /tmp/screenshot.png # スクリプトを WSL から実行(Windows Python が呼ばれる) winauto run my_automation.py # ヘルパースクリプトは Windows Python 経由で実行 cmd.exe /c python .github/skills/windows-app-automation/scripts/element_inspector.py --list ``` **WSL 固有の注意点:** - ラッパーは Windows の `python.exe` を**直接 exec** する(`cmd.exe` を挟まない)。 `cmd.exe` 経由だと WSL の cwd に対して「CMD does not support UNC paths as current directories」を吐き、出力を読むエージェントを惑わせるため - **引数のパス変換はラッパーが行うが、変換対象は限定されている**。変換されるのは `screenshot` / `codegen` / `record` の `--output` の値、`run` のスクリプト位置引数、 および `/` で始まる絶対パスだけ。セレクタ(`name:=OK`)や `type` に渡す入力テキストは **変換しない**(同名のファイルが cwd にあるだけで壊れるのを避けるため) - `winauto run` に渡す**スクリプトの中身**のパスは Windows パス(`C:/...`)で書く ——変換されるのはコマンドライン引数だけで、スクリプト本文は解釈しない - `WINAUTO_NO_PATH_CONV=1` で変換を完全に無効化できる - WSL ターミナルに出力は返ってくるが、GUI 操作の対象は Windows デスクトップ上のウィンドウ ### kiro-cli から呼び出す場合 kiro-cli は WSL 上で動作する AI エージェント CLI。`--trust-all-tools` を付けると winauto コマンドを 自律的に呼び出してスクリプトを生成・実行できる。詳細は `references/kiro-cli-usage.md` を参照。 **基本パターン:** ```bash # タスク記述に「winauto CLI が使える」と明示するとエージェントが活用する kiro-cli chat --no-interactive --trust-all-tools \ "Notepad を起動してテキストを入力してスクリーンショットを /tmp/sc.png に保存して。winauto CLI が使える。" ``` **自動実行フロー:** ``` kiro-cli --trust-all-tools ├─ winauto apps ← 起動中アプリを偵察 ├─ winauto tree --app <name> ← UI 要素を偵察 ├─ [Python スクリプト生成] ← pywinauto スクリプトをファイルに書く ├─ winauto run script.py ← 実行(Windows Python が動く) └─ winauto screenshot ← 結果を画像で確認 ``` **kiro-cli 固有の注意点:** - `--trust-all-tools` がないと winauto などの外部コマンド実行が承認待ちになる - GUI 操作は Windows デスクトップ側で発生するため stdout に状況は出ない。`winauto screenshot` で確認 - kiro-cli が生成したスクリプト内の Windows パスは `C:/...` 形式にする --- ## 並列実行とデスクトップ排他 **Windows デスクトップは 1 セッションに 1 つしかない共有排他資源**。フォーカスとマウスカーソルは 1 組しかないため、複数プロセスが同時に `set_focus()` / `click_input()` を撃つと互いの操作を 奪い合って壊れる。agent-flow を `--workers 3` のように並列で回すと即座にこれが起きる。 winauto は**入力・フォーカスを奪うコマンドをファイルロックで直列化**する(既定で有効)。 | | コマンド | |---|---| | ロックを取る | `launch` `click` `type` `select` `keys` `screenshot` `run` `inspect` `codegen` | | ロックを取らない | `apps` `tree` `get-text` `wait` `doctor` `record` | 読み取り専用をロック対象から外してあるのは、長い `wait` がロックを占有して他の発行を 止めてしまわないようにするため。 WSL からの呼び出しもラッパー経由で Windows Python に収束するので、**ロック 1 本で 「WSL 発」と「Windows ネイティブ発」の双方が直列化される**。分散実行(`agent-flow --git`)では PC ごとにデスクトップが別なので、PC 単位でロックが閉じるこの構造が意味論的にも正しい。 ```bash winauto --lock-timeout 600 click "name:=OK" --app myapp # ロック待ちの上限(既定 300 秒・0 で無限) winauto --no-lock screenshot --app myapp # 排他を外す(並列 GUI 操作は壊れる) WINAUTO_LOCK_TIMEOUT=600 winauto click ... # 環境変数でも指定可 ``` ロック待ちの告知と待ちタイムアウトは **stderr** に出る(stdout はエージェントが読む結果なので汚さない)。 誰が握っているかは `winauto doctor` の `lock` 行で分かる。 **agent-flow から使うときの注意:** - GUI ノードは Windows デスクトップのある PC でしか実行できない。分散時は GUI 対応 PC だけが `participate` するバス/ブランチに分ける - `agent_timeout`(既定 600 秒)は GUI タスクには短いことがある。ロック待ち時間も含まれる点に注意 - 画面ロック中・RDP 切断中・未ログオンのセッションでは GUI 操作もスクリーンショットも失敗する。 `winauto doctor` の `desktop` 行が warn を出す --- ## 利用可能な補助スクリプト - `scripts/element_inspector.py` — UIツリーの探索・セレクタの特定(最初に必ず実行) - `scripts/app_launcher.py` — アプリ起動・待機・コマンド実行・終了を一括管理 - `tools/winauto/winauto.py` — Playwright 風の統合 CLI(inspect/click/type/select/screenshot/codegen/record) **最初に `--help` を実行して利用方法を確認する。必要になるまでスクリプト本体は読まない。** ## 進め方の判断フロー ``` 依頼内容 → 対象アプリは何か? ├─ Win32 (MFC / VCL / Delphi / 古いC++) → backend=win32 を優先 ├─ WPF / UWP / WinForms / Qt → backend=uia を使う └─ 不明 → uia から試し、失敗なら win32 アプリは起動済みか? ├─ No → Application.start(app_path) で起動 └─ Yes → Application.connect(title_re / process) でアタッチ 要素が見つかるか? → 必ず先に element_inspector.py で探索する ├─ auto_id あり → child_window(auto_id="...") ← 最優先 ├─ name + type → child_window(title="...", control_type="...") └─ class あり → child_window(class_name="...") ← Win32 向け ``` ## ワークフロー: 調査 → 生成 → 実行 ### Step 1: 要素ツリーを探索する ```bash # アプリ一覧を確認 python scripts/element_inspector.py --list # UIツリーを探索(depth は 3〜5 が目安) python scripts/element_inspector.py --app notepad --depth 4 # 特定の子要素から探索 python scripts/element_inspector.py --app notepad --selector "control:=Document" # JSON で出力(大きなツリーの解析に便利) python scripts/element_inspector.py --app notepad --json > tree.json ``` winauto CLI でも同等の操作が可能: ```bash python tools/winauto/winauto.py apps python tools/winauto/winauto.py tree --app notepad --depth 4 python tools/winauto/winauto.py inspect --app notepad # 対話REPL ``` ### Step 2: スクリプトを生成する ```bash # codegen でテンプレートを生成(アプリを起動してツリーを取得) python tools/winauto/winauto.py codegen notepad.exe --output test_notepad.py # 生成されたスクリプトを確認・編集して完成させる ``` または、手動で直接スクリプトを書く(Step 1 で取得したセレクタを使う)。 **人にやって見せてもらう(record)** — 手順が言葉で書き取りにくいときは、操作を記録する。 ```bash winauto record --app 勤怠管理 --output events.jsonl # 人がアプリを操作する → Ctrl+C で止める ``` 1 行 1 JSON(JSONL)で、押した要素・入力欄の確定値・選択・チェック・ウィンドウの 切り替わりが残る。**打鍵そのものは記録しない**——低レベルキーボードフックは デスクトップ全体のキーロガーになり、対象アプリ以外へ打ったパスワードまで拾うため。 入力欄へ打った文字は `value` として、キーボードから開いたメニューは `invoke` として 残るので、実務上の穴は「UI に対応物の無いショートカット」だけである(必要なら `{"event":"keys",...}` の行を手で足す)。 記録の 1 行は**そのまま打てる argv ではなく、何が起きたかの事実**である。再現するときは `launch` → `winauto launch`、`window` → その画面を `winauto wait` で待つ、 `click` / `toggle` → `winauto click`、`value` → `winauto type`、 `select` → `winauto select <セレクタ> <項目名>` と読み替える。 agent-dashboard の「手順を組み立てる → 操作を記録する」に貼り付けると、工程列に変換される。 ### Step 3: 実行する ```bash # 単体実行 python my_automation.py # app_launcher.py 経由(アプリ起動・終了を自動管理) python scripts/app_launcher.py --app notepad.exe -- python my_automation.py # winauto CLI でワンライナー実行 python tools/winauto/winauto.py click "name:=OK" --app notepad ``` --- 起動・接続、要素の検索、操作、スクリーンショット、ダイアログ処理の定型コードは `references/pywinauto-patterns.md` にまとめてある。 --- ## コントロールタイプ別 Tips ### リストボックス / コンボボックス ```python # ListBox: アイテム選択 lb = win.child_window(control_type="ListBox") lb.select("Item Name") # 名前で選択 lb.get_item(0).click_input() # インデックスで選択 # ComboBox: ドロップダウン cb = win.child_window(control_type="ComboBox") cb.select("Option 1") # 項目を選択 items = cb.item_texts() # 全項目取得 # ListBox のアイテムを全取得 items = [item.window_text() for item in lb.children()] ``` ### ツリービュー ```python tv = win.child_window(control_type="Tree") # ルートアイテム取得 roots = tv.children(control_type="TreeItem") # 子アイテム展開 root = roots[0] root.expand() children = root.children(control_type="TreeItem") # パスで選択 tv.get_item(r"\Root\Child\Grandchild").select() ``` ### チェックボックス / ラジオボタン ```python cb = win.child_window(title="Enable feature", control_type="CheckBox") cb.check() # チェック ON cb.uncheck() # チェック OFF is_checked = cb.get_toggle_state() == 1 rb = win.child_window(title="Option A", control_type="RadioButton") rb.select() ``` ### タブコントロール ```python tab = win.child_window(control_type="Tab") tab.select("Settings") # タブ名で選択 tab.select(1) # インデックスで選択 ``` --- ## よくある落とし穴と対処法 | 症状 | 原因 | 対処 | |------|------|------| | `ElementNotFoundError` | セレクタが間違い / UIが未描画 | `element_inspector.py` で再確認; `wait()` を追加 | | 操作が失敗・無応答 | 要素が disabled / focus なし | `wait("enabled")` → `set_focus()` → `click_input()` | | テキスト入力が文字化け | IME / Unicode 問題 | `type_keys()` の代わりに `set_text()` を使う | | `click()` が効かない | 座標クリックが必要 | `click_input()` を使う(より低レベル) | | ダイアログが検出できない | タイトルの一致パターンが違う | `title_re=".*キーワード.*"` で部分一致 | | `backend=uia` で要素が見えない | アプリが UIA 非対応 | `backend=win32` に切り替える | | 高速実行で要素見つからない | UI描画遅延 | `win.wait("ready")` / `elem.wait("exists")` を使う | | 管理者権限アプリを操作できない | UAC 分離 | スクリプト自体を管理者権限で実行 | | **WSL**: `pywinauto` が import できない | Linux Python に入っている | Windows Python で実行する: `cmd.exe /c python script.py` | | **WSL**: `winauto` コマンドが見つからない | インストール未完 / PATH 未設定 | `python tools/winauto/install.py` を再実行; `source ~/.bashrc` | | **WSL**: `winauto apps` が空 | WSL から Windows デスクトップが見えない | `winauto doctor` で interop / ラッパー / デスクトップ到達性を切り分ける | | 操作が数分止まったまま | 別プロセスが GUI ロックを保持している | `winauto doctor` の `lock` 行で保持者を確認。並列度を下げるか `--lock-timeout` を延ばす | | `GUI ロックを … 秒以内に取得できませんでした` | 先行の GUI 操作が長い/異常終了 | `--lock-timeout 0`(無限待ち)か、保持者プロセスを終了させる | | スクリーンショットが真っ黒/ウィンドウが 0 個 | 画面ロック中・RDP 切断中・未ログオン | セッションをアンロックした状態を保つ。`winauto doctor` の `desktop` 行で検知できる | | **Copilot**: ターミナルで `python` が見つからない | PATH に Python が未登録 | VS Code の Python インタープリタ設定を確認; `where python` でパスを確認 | | **Kiro**: エージェントが winauto を実行できない | Kiro がシェルコマンドをブロック | Kiro の設定で `trustTools: true` を確認; 手動でターミナル実行 | --- ## ベストプラクティス - **必ず先に explorer で探索する**: `element_inspector.py --app <name>` でセレクタを確認してからスクリプトを書く - **`auto_id` を最優先にする**: 開発者が設定した AutomationID は最も安定したセレクタ - **`wait()` を省略しない**: `click_input()` の前に必ず `wait("enabled")` か `wait("exists")` を入れる - **`click_input()` を使う**: `click()` より確実。マウスイベントを直接送信する - **`set_text()` を使う**: `type_keys()` は IME 問題が起きやすい。値を確定させるだけなら `set_text()` が確実 - **`app_launcher.py` でライフサイクル管理**: アプリの起動・終了をスクリプト内に書かず、`app_launcher.py` に任せる - **スクリーンショットで状態確認**: エラー時は `capture_as_image().save()` で状態を記録する --- ## 参照 - `references/selector-syntax.md` — セレクタ構文の詳細リファレンス - `references/pywinauto-patterns.md` — 起動・検索・操作・ダイアログの基本パターン集 - `examples/notepad_automation.py` — Notepad 自動化の完全サンプル - `examples/file_dialog_handling.py` — ファイルダイアログ操作パターン集 - `tools/winauto/winauto.py` — winauto CLI(`--help` で各コマンド確認) - [pywinauto Documentation](https://pywinauto.readthedocs.io/) - [Windows UI Automation](https://learn.microsoft.com/windows/win32/winauto/entry-uiauto-win32)
View on GitHub