Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Periksa dan berinteraksi dengan menjalankan aplikasi Windows dari baris perintah. Digunakan oleh agen dan pengembang AI untuk pengujian, penelusuran kesalahan, dan otomatisasi UI.
Ikhtisar
winapp ui menyediakan perintah untuk memeriksa dan berinteraksi dengan UI aplikasi Windows.
Menggunakan Windows UI Automation (UIA). Bekerja dengan aplikasi Windows apa pun — WPF, WinForms, Win32, Electron, dan WinUI 3.
Sebagian besar perintah mendorong aplikasi melalui pola UIA (tanpa injeksi input). Pengecualian menyuntikkan input nyata: ui click/ui hover/ui dragmenggunakan simulasi mouse,ui touch/ui pen mensintesis sentuhan dan input pena/stylus, dan ui send-keys mensintesis input keyboard — untuk kontrol dan skenario yang tidak dapat didorong oleh pola UIA.
Important
Persyaratan interaktif-desktop (kata kerja input-menyuntikkan).click, , hover, drag, touch, penscroll --wheel, , dan send-keys --via send-input mensintesis input tingkat OS, sehingga mereka memerlukan desktop interaktif yang tidak terkunci dengan jendela target di latar depan. Pada stasiun kerja terkunci atau desktop aman (LogonUI/UAC) mereka tidak dapat menyuntikkan dan gagal dengan cepat dengan no_interactive_desktop (berbeda dari elevasi/foreground_not_target kasus).
touch
/
pen selain itu menolak ketika tidak ada jendela yang menyelesaikan (no_target); koordinat di luar jendela target adalah peringatan non-fatal ( warnings[] entri di bawah --json, atau baris peringatan dalam mode teks) dan injeksi masih berlanjut — konsisten dengan kata kerja mouse. Segala sesuatu yang lain — inspect, , search, get-propertyget-value, wait-for, set-value, invoke, scroll --direction/--to - mendorong aplikasi melalui pola UIA dan ramah tanpa kepala / sesi terkunci.
screenshot adalah pengecualian di antara kata kerja yang tidak menyuntikkan: dibutuhkan giliran eksklusif dan penangkapannya dapat membutuhkan desktop interaktif yang dapat digunakan, karena mesin memulihkan target yang diminimalkan dan kembali ke latar depan ketika pengambilan bingkai tidak tersedia atau --capture-screen digunakan. Lebih suka kata kerja pola UIA di CI; cadangkan kata kerja injeksi untuk skenario yang benar-benar membutuhkan input nyata. Sebelum menyuntikkan, kata kerja gerakan juga menyelesaikan kembali elemen target dan menolak jika target_moved masih meniru/merelokasi, daripada mendaratkan input pada ruang kosong.
Mulai Cepat
# 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
Menjalankan otomatisasi UI di Windows Sandbox
Untuk menjaga automasi tetap di luar desktop Anda, tambahkan --on sandbox ke perintah jalankan dan UI:
winapp run . --on sandbox --detach
winapp ui inspect --on sandbox -a MyApp
winapp ui invoke --on sandbox SubmitButton -a MyApp
--detach kembali setelah peluncuran; tanpanya, run menunggu aplikasi keluar. Terus --on sandbox pada setiap perintah tamu, termasuk yang menggunakan PID atau handel jendela.
Lihat Windows eksekusi Sandbox untuk persyaratan klien, pengaturan singkat/sambungkan kembali perubahan fokus, koordinasi alur kerja, dan pengiriman output host.
Kueri terlingkup dan dititik
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
search, , get-propertyget-value, dan wait-for terima filter opsional ini.
Pemilih dan setiap filter yang disediakan harus cocok dengan elemen yang sama:
-
--root <selector>hanya mencari keturunan dari satu akar yang cocok secara unik, tidak pernah akar itu sendiri. Gunakan AutomationId atau slug dariinspectuntuk memisahkan. Akar yang cocok dengan beberapa elemen gagal denganambiguous_selector, bahkan jika satu kecocokan dapat dipanggil. Akar yang hilang tidak menghasilkan kecocokan. Setelah akar ditemukan, kueri tidak mencari jendela popup yang tidak terkait, bahkan ketika tidak ada kecocokan turunan. Kueri tidak dibatasi olehinspectkedalaman tampilan. -
--type <control-type>cocok dengan jenis kontrol UIA, mengabaikan kasus. Satu-satunya alias adalahTextBox→EditdanTextBlock→Text. Nama yang tidak diketahui (termasuk ID numerik dan ekspresi kartubebas) gagal denganinvalid_arguments. -
--class-name <literal>cocok dengan seluruh UIAClassNamepenyedia, mengabaikan kasus. Ini bukan substring, kartubebas, atau ekspresi reguler. Gunakanget-property --property ClassNameuntuk menemukan nilai penyedia; nama kelas tidak perlu sama dengan jenis kontrol UIA.
Kueri yang difilter menggunakan Tampilan Kontrol UIA, tampilan yang sama diperlihatkan oleh inspect.
Node penyedia yang hanya diekspos dalam Tampilan Mentah tidak dikembalikan; gunakan inspect untuk menemukan kontrol yang berisi dan pemilihnya.
Semua 41 jenis resmi didukung: Button, CustomComboBoxCheckBoxHyperlinkEditImageListItemListMenuMenuBarCalendarTextTabItemTabStatusBarToolBarSpinnerSliderScrollBarToolTipRadioButtonProgressBarMenuItemTreeTreeItemSplitButtonDocumentWindowDataItemPaneDataGridHeaderHeaderItemThumbGroupTitleBarSeparatorTableSemanticZoom, . AppBar
wait-for menyelesaikan pemilih akar lagi pada setiap polling, sehingga akar mungkin muncul setelah perintah dimulai. Dengan --gone, akar absen berarti tidak ada keturunan yang cocok; akar ambigu adalah kesalahan, bukan keberhasilan.
Pencarian yang terganggu bukan bukti hilangnya: jika elemen dihapus selama pencarian atau diganti sebelum --value dibaca, polling berikutnya memeriksa lagi; kesalahan pencarian atau baca lainnya gagal perintah.
-w <HWND> membatasi penemuan akar ke pohon UIA jendela tersebut. Dengan -a, penemuan akar juga dapat menemukan jendela popup aplikasi. Kecocokan AutomationId akar yang tepat lebih diutamakan daripada kecocokan substring di semua jendela tersebut; beberapa kecocokan persis masih gagal dengan ambiguous_selector.
Simpul akar memilih elemen tersebut bahkan ketika jendela lain memiliki AutomationId yang sama. Jika akar yang dipilih diganti, simpul lamanya tidak lagi cocok; gunakan AutomationId atau akar nama saat Anda ingin polling mengikuti penggantian.
Saat filter ada, perintah yang membaca elemen tunggal gagal dengan ambiguous_selector jika lebih dari satu elemen tetap ada; persempit filter atau gunakan simpul unik. AutomationId yang tepat cocok mempertahankan prioritas daripada kecocokan substring, dalam cakupan yang difilter. Menghilangkan ketiga opsi mempertahankan perilaku kueri yang ada.
Mengoordinasikan alur kerja UI bersamaan
Windows hanya memiliki satu jendela latar depan, satu fokus keyboard, satu kursor, dan satu aliran input. Ketika dua winapp ui alur kerja berjalan pada desktop masuk yang sama sekaligus, mereka dapat mencuri fokus satu sama lain, menutup menu yang baru saja dibuka, atau memindahkan target keluar dari bawah klik tertunda.
Arbitrase selalu aktif. Setiap winapp ui perintah yang menyentuh desktop fisik bergantian, tanpa pengaturan dan tidak ada cara untuk mematikannya, sehingga dua agen tidak pernah dapat mengetik ke jendela satu sama lain. Perintah baca-saja terus berjalan secara bersamaan.
Kelangsungan antar perintah adalah keikutsertaan. Secara default setiap perintah adalah satu bidikan mandiri: perintah menunggu gilirannya, melakukan pekerjaannya, dan segera merilis desktop. Untuk mempertahankan desktop di beberapa perintah, berikan semua id alur kerja yang sama:
# Set once per logical UI workflow
$env:WINAPP_UI_WORKFLOW_ID = [guid]::NewGuid().ToString()
Yang perlu Anda ketahui:
- Id alur kerja menamai satu alur kerja logis — belum tentu merupakan seluruh agen, dan belum tentu satu aplikasi. Gunakan nilai yang sama untuk bekerja sama dengan perintah (rekaman ditambah klik yang harus diambilnya); gunakan nilai yang berbeda untuk alur kerja independen, bahkan ketika satu agen meluncurkan keduanya.
- Tanpa id, setiap perintah adalah satu bidikan independen. Ini masih arbitrase, tetapi tidak bank rahmat dan tangan desktop off saat selesai. Dua perintah no-id adalah alur kerja terpisah bahkan ketika diluncurkan dari shell yang sama.
- Host fresh-shell dan adaptif harus menyuntikkan nilai yang sama. Jika setiap perintah berjalan di shell baru — yaitu cara kerja sebagian besar alat agen — satu-satunya hal yang dapat mengelompokkannya adalah eksplisit
WINAPP_UI_WORKFLOW_IDyang diteruskan ke setiap panggilan yang bekerja sama. - Tenggang empat detik melindungi ledakan ketat, bukan penalaran model. Alur kerja dengan id menyimpan gilirannya selama perintah berikutnya dimulai dalam waktu empat detik. Itu mencakup perintah back-to-back dalam satu skrip; itu sengaja kedaluwarsa saat model sedang berpikir. Ini adalah fallback ketika Anda tidak dapat mengatakan Bahwa Anda selesai — ketika Anda bisa, jalankan
winapp ui yieldalih-alih menunggu. - Alur kerja adaptif harus membutuhkan kembali, memvalidasi ulang, dan memutar ulang. Setelah celah penalaran, alur kerja lain mungkin telah menggunakan desktop, jadi buka kembali menu, atasi kembali elemen, lalu bertindak. Kirim urutan end-to-end yang diketahui sebagai satu skrip ketat daripada menahan desktop saat Anda berpikir.
- Pemesanan adalah afinitas pemilik terlebih dahulu, kemudian FIFO di antara yang lain. Meskipun alur kerja aktif atau di dalam rahmatnya, alur kerja mungkin tetap mengeluarkan perintah, bahkan jika alur kerja lain sudah menunggu. Setelah berjalan
winapp ui yieldatau tenggangnya kedaluwarsa, alur kerja tunggu disajikan dalam urutan kedatangan yang ketat. Oleh karena itu, aktivitas berkelanjutan menurut satu alur kerja dapat menunda orang lain tanpa batas waktu. - Tidak ada topi keras. Skrip panjang, rekaman yang tidak terbatas, atau perulangan kegagalan dapat memblokir alur kerja bermutasi lainnya.
-
Pembatalan atau penghentian proses adalah pemulihan untuk alur kerja langsung yang macet. Perintah menunggu mencetak status setelah satu detik dan dapat dihentikan dengan
Ctrl+C, yang keluar130. - Hanya biner yang diperbarui yang kompatibel yang bekerja sama. Build yang lebih
winapplama mendahului fitur ini dan tidak dikoordinasikan. Kode yang memanggil paket UI Automation NuGet secara langsung berada di luar jaminan ini sepenuhnya — koordinasi hidup di CLI, bukan dalam paket.
Perintah mana yang menunggu giliran:
| Behavior | Commands |
|---|---|
| Berjalan bersamaan (tidak pernah menunggu) |
status, , inspectlist-windows, search, get-property, get-value, , get-focused,wait-for |
| Menunggu giliran tetapi tidak pernah mengambil desktop |
set-value, , scroll-into-view/scroll --direction--to,record |
| Menunggu giliran dan mengambil desktop secara eksklusif |
invoke, click, drag, hover, scroll --wheel, touch, pen, focus, send-keys, screenshot |
Baris tengah adalah yang layak dipahami.
set-value, scroll-into-view dan scroll --direction/--to mendorong pola UIA daripada latar depan, sehingga tetap headless/sesi terkunci ramah dan tidak pernah memblokir siapa pun menggunakan desktop. Tetapi mereka mengubah apa yang ditunjukkan aplikasi, sehingga mereka menunggu di belakang giliran alur kerja lain daripada mengedit bidang atau menggulir daftar keluar dari bawah klik orang lain.
Dalam satu alur kerja, mereka tumpang tindih dengan pekerjaan bersama lainnya — itulah cara merekam recordset-value panggilan yang direkam. Mereka tidak mengabaikan penghalang maju alur kerja mereka sendiri: perintah sebelumnya DesktopExclusive dari alur kerja yang sama (a click, a screenshot) masih memblokirnya, persis seperti memblokir setiap perintah nanti, jadi klik dan mutasi yang mengikutinya tetap dalam urutan Anda menulisnya.
screenshot selalu mengantre untuk giliran eksklusif. Tidak setiap tangkapan mengganggu desktop — jendela yang terlihat biasa yang diambil melalui Windows Graphics Capture tidak — tetapi mesin memulihkan target jika diminimalkan, dan kembali ke latar depan saat pengambilan bingkai tidak tersedia atau --capture-screen membaca layar langsung. Kebutuhan tersebut hanya permukaan setelah penangkapan sedang berlangsung, sehingga perintah mengambil giliran di depan daripada menebak. Ketika menggabungkan beberapa jendela, itu menangkap mereka semua di bawah satu giliran eksklusif, sehingga gambar yang disimpan adalah satu momen yang konsisten daripada campuran sebelum dan sesudah. Pengodean dan penulisan file terjadi setelah desktop dirilis.
--capture-screenmembutuhkan tepat satu jendela. Tangkapan layar langsung merekam apa pun yang sebenarnya ada di depan, dan hanya satu jendela yang bisa. Memilih jendela secara eksplisit dengan-w <hwnd>memberinya tepat satu wilayah — piksel di dalam batas jendela tersebut, termasuk dialog atau overlay yang terlihat di atasnya, yang merupakan alasan untuk membaca layar di tempat pertama. Ketika-acocok dengan beberapa jendela tingkat atas atau milik tidak ada pilihan seperti itu, sehingga perintah gagal denganinvalid_argumentssebelum menangkap apa pun daripada melawan latar depan. Jalankanwinapp ui list-windows -a <app>dan coba lagi dengan-w <hwnd>, atau jatuhkan--capture-screenuntuk menyusun setiap jendela dari kontennya sendiri.
record membagikan gilirannya, sehingga input alur kerja yang sama dapat bersinggungan dengan pengambilan — itulah cara Anda merekam alur kerja yang mengendarai aplikasi. Dua peringatan:
-
recordTanpa id alur kerja adalah pemilik satu bidikan, sehingga memblokir setiap alur kerja lainnya selama seluruh durasinya. Untuk merekam dan mengklik pada saat yang sama, berikan kedua perintah yang samaWINAPP_UI_WORKFLOW_ID. - Pada host tanpa dukungan pengambilan bingkai, rekaman kembali ke PrintWindow, yang pemulihan bingkai kosongnya dapat memajukan jendela kapan saja. Di sana desktop ditahan untuk seluruh rekaman dan perintah mengatakan demikian dalam outputnya; bahkan input alur kerja yang sama akan menunggu.
Kesalahan yang mungkin Anda lihat: invalid_ui_workflow_id (variabel diatur tetapi kosong atau lebih dari 256 karakter), desktop_coordination_unavailable (status koordinasi tidak dapat dibaca dan tidak dapat dibangun kembali dengan aman, atau ditulis oleh yang lebih winappbaru ), queue_capacity_exceeded (64 perintah dari alur kerja lain sudah menunggu - batas menghitung pelayan asing langsung, bukan proses yang telah Anda mulai, sehingga entri milik perintah yang telah keluar atau telah dimatikan tidak menempati slot, dan perintah alur kerja Anda sendiri mengantre di belakang satu sama lain daripada terhadap batas ini), ui_turn_busy (yield sementara alur kerja Anda sendiri masih memiliki perintah yang berjalan), dan cancelled (Ctrl+C saat menunggu, keluar dari kode 130).
Melepaskan belokan lebih awal: winapp ui yield
Rahmat empat detik adalah fallback: ini menjaga desktop dicadangkan ketika Anda tidak dapat mengatakan dengan pasti bahwa Anda selesai. Ketika Anda dapat mengatakan demikian, katakanlah — yield tangan desktop segera alih-alih membuat orang lain menunggu kasih karunia yang tidak dibutuhkan.
$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
- Perintah satu bidikan tidak boleh mengatur id alur kerja sama sekali. Tanpa satu perintah, setiap perintah sudah merilis desktop saat selesai, dan tidak ada yang bisa dihasilkan.
- Alur kerja multi-langkah harus menghasilkan setelah selesai, terutama ketika alur kerja lain mungkin menunggu. Biayanya satu perintah cepat dan menghapus kios empat detik dari orang lain.
- Ini idempotensi. Menghasilkan dua kali, atau setelah anugerah telah terhenti, berhasil, dan melaporkan
{ "released": false }— itu adalah akhir normal dari skrip, bukan kegagalan. - Ini tidak pernah merilis giliran alur kerja lain. Jika orang lain memegang desktop, atau tidak ada yang melakukannya, itu adalah no-op.
- Ini gagal dengan
ui_turn_busyjika alur kerja Anda sendiri masih memiliki perintah yang berjalan atau diantrekan — rekaman, katakanlah. Melepaskan di bawahnya yang akan menyerahkan desktop ke tengah perintah, jadi tidak ada yang dirilis dan perintah yang sedang berjalan tidak terpengaruh. Tunggu atau hentikan, lalu hasilkan lagi. - Ini membutuhkan
WINAPP_UI_WORKFLOW_ID. Tanpa salah satu itu gagal denganinvalid_arguments. - Tidak memerlukan aplikasi dan tidak ada pemilih: itu mengembalikan reservasi, bukan jendela, sehingga masih berfungsi setelah aplikasi ditutup.
Perintah menunggu dibangunkan oleh siapa pun yang merilis desktop daripada dengan polling untuk itu, sehingga antrean hampir tidak dikenakan biaya saat menunggu dan handoff segera. Setiap pelayan juga sesekali melakukan pemeriksaan ulang sendiri, yang merupakan apa yang memulihkan desktop ketika proses dimatikan dan tidak pernah menerbitkan apa pun: perintah di kepala antrean terlihat setiap setengah detik, dan perintah di belakangnya - yang tidak dapat berjalan sebelum kepala tetap melakukannya — setiap beberapa detik.
Menargetkan Aplikasi
Menurut nama proses
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
Menurut judul jendela
winapp ui inspect -a "LICENSE - Notepad"
winapp ui inspect -a "Fix WinApp" # partial title match
Menurut PID
winapp ui inspect -a 12345
Menurut HWND (stabil — bertahan dari perubahan tab/judul)
# 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
Gunakan -a untuk penemuan, -w untuk penargetan yang stabil. Saat -a cocok dengan beberapa jendela, perintah mencantumkannya dengan HWND untuk Anda pilih.
Selektor
Elemen target menggunakan pemilih yang ditampilkan dalam [brackets] output inspeksi/pencarian.
Ada tiga jenis pemilih:
| Selector | Makna | Example |
|---|---|---|
MinimizeButton |
AutomationId (ditampilkan saat unik — stabil, lebih disukai) | winapp ui invoke MinimizeButton -a myapp |
btn-close-d1a0 |
Simpul semantik (ditampilkan ketika tidak ada AutomationId yang unik) | winapp ui invoke btn-close-d1a0 -a myapp |
Submit |
Pencarian teks biasa terhadap Name/AutomationId (substring tidak peka huruf besar/kecil) | winapp ui invoke Submit -a myapp |
Pemilih AutomationId adalah pengidentifikasi set pengembang (AutomationProperties.AutomationId di XAML).
Ketika AutomationId unik di seluruh pohon UI, inspect dan search memperlihatkannya langsung sebagai pemilih - ini bertahan dari perubahan tata letak, pelokalan, dan restrukturisasi pohon.
Pemilih simpul (misalnya, btn-close-d1a0) dihasilkan ketika tidak ada AutomationId unik.
Format: prefix-name-hash. Hash memvalidasi identitas elemen tetapi mungkin kedaluarsa setelah UI berubah.
Memeriksa format output
inspect Perintah menunjukkan pohon elemen dengan output berwarna (pemilih dalam sian, nama berwarna hijau, metadata berwarna abu-abu):
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
Kata pertama pada setiap baris adalah pemilih — gunakan dengan perintah lainui.
Ketika elemen memiliki AutomationId yang unik, elemen tersebut digunakan secara langsung (misalnya, TabView, NewTabButton).
Ketika tidak ada AutomationId unik, simpul yang dihasilkan digunakan (misalnya, tab-newtab-5f5b).
Simpul semantik
Simpul menggunakan format : prefix-normalizedname-hash di mana:
- awalan — singkatan jenis 3 huruf (btn, txt, chk, cmb, itm, tab, img, lbl, pn, win, grp, lnk, mnu, dll.)
- normalizedname — huruf kecil alfanumerik dari AutomationId (lebih disukai) atau Nama, maks 15 karakter
- hash — hash 4-char hex dari RuntimeId elemen (memvalidasi identitas elemen)
Simpul aman shell (tanpa karakter khusus), unik, dan dapat digunakan langsung sebagai argumen. Tanpa filter kueri, hash menyediakan deteksi keusangan — jika elemen telah diganti, Anda mendapatkan: "Elemen mungkin telah berubah. Jalankan kembali inspeksi." Untuk kueri yang difilter, lihat Kueri terlingkup dan ditik.
Elemen tanpa nama atau AutomationId hanya menunjukkan awalan + hash (misalnya, pn-c8a3).
Mendisambiguasi beberapa kecocokan
Simpul dari inspect/search output bersifat unik, tetapi dapat berubah di seluruh perubahan tata letak - gunakan melalui nama atau teks jenis biasa saat beberapa kecocokan. Ketika pemilih ambigu, CLI mencetak semua kecocokan dengan simpulnya sehingga Anda dapat memilih yang tepat dan menjalankan kembali dengan simpul tersebut.
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
Pencarian teks biasa
Gunakan teks biasa untuk mencari elemen — tidak diperlukan sintaksis khusus:
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
Saat pencarian teks cocok dengan beberapa elemen (misalnya, PengaturanExpander di mana Grup, Tombol, dan Teks semuanya memiliki nama yang sama), CLI secara otomatis memilih satu-satunya elemen yang dapat dipanggil. Jika beberapa dapat dipanggil, ia mencantumkan semua kecocokan dengan simpul.
Untuk hasil pencarian yang tidak dapat dipanggil (misalnya, TextBlock di dalam Tombol), pencarian secara otomatis menampilkan leluhur terdekat yang dapat dipanggil — elemen induk yang dapat Anda gunakan dengan invoke.
Ini berfungsi untuk semua pemilih pencarian:
lbl-savechanges-a1b2 "Save changes" (120,40 80x20)
^ invoke via: btn-save-c3d4 "Save"
Pemilih yang muncul dapat digunakan secara langsung:
winapp ui invoke btn-save-c3d4 -a myapp # invoke the parent Button
Commands
status
Sambungkan ke aplikasi dan tampilkan info koneksi.
winapp ui status -a notepad
winapp ui status -a notepad --json
Memeriksa
Lihat pohon elemen UI. Output menunjukkan simpul semantik dengan indentasi 2 spasi untuk hierarki:
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
Contoh output (default):
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)
Contoh output (--interactive — hanya elemen yang dapat dipanggil, daftar datar):
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)
Elemen dapat menunjukkan penanda status ini:
-
[on]/[off]/[indeterminate]— status toggle/checkbox -
[collapsed]/[expanded]— perluas/ciutkan status untuk pohon, kotak kombo, item menu -
[scroll:v]/[scroll:h]/[scroll:vh]— kontainer yang dapat digulir (vertikal, horizontal, atau keduanya) -
[offscreen]— elemen tidak terlihat di layar -
[disabled]— elemen tidak diaktifkan -
value="..."— konten teks saat ini untuk elemen yang dapat diedit (jika berbeda dari Nama)
cari
Temukan elemen yang cocok dengan pemilih. Output menunjukkan simpul semantik:
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
Contoh output:
btn-minimize-d1a0 "Minimize" (1222,206 48x48)
btn-maximize-e2b1 "Maximize" (1270,206 48x48)
btn-close-d1a2 "Close" (1318,206 48x48)
Simpul yang ditampilkan dalam output (misalnya, btn-minimize-d1a0) dapat digunakan langsung dengan perintah lain:
winapp ui invoke btn-minimize-d1a0 -a notepad
get-property
Membaca nilai properti dari elemen. Termasuk status khusus pola (ToggleState, Value, IsSelected, dll.).
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
Nama properti peka huruf besar/kecil. Nama yang tidak diketahui gagal dengan invalid_arguments di bawah --json; hilangkan --property untuk mencantumkan properti, termasuk keenam atribut pemformatan teks di bawah ini.
wait-for --property menggunakan nama peka huruf besar/kecil yang sama dan menolak nama yang tidak diketahui sebelum polling.
Pemformatan teks seluruh dokumen
Pemformatan dibaca di seluruh dokumen TextPattern elemen, bukan pilihan atau tanda sisipan saat ini. Bacaan tidak mengubah fokus atau pilihan.
| Harta benda | Nilai seragam (dikembalikan sebagai string) |
|---|---|
FontWeight |
Berat numerik, seperti "400" (normal) atau "700" (tebal) |
FontName |
Nama keluarga font, seperti "Courier New" |
FontSize |
Ukuran dalam poin, seperti "15.5" |
ForegroundColor |
Desimal Windows COLORREF (0x00BBGGRR), seperti "3678732" untuk RGB(12, 34, 56) |
IsItalic |
"True" atau "False" |
StrikethroughStyle |
Gaya dekorasi teks UIA numerik, seperti "0" (tidak ada) atau "1" (tunggal) |
Angka menggunakan pemformatan invarian (titik desimal, terlepas dari lokal Anda). Setiap atribut dapat mengembalikan:
| Nilai | Arti dan langkah berikutnya |
|---|---|
"Mixed" |
Pemformatan bervariasi dalam dokumen. Jangan perlakukan sebagai nilai seragam; perintah ini tidak mengkueri rentang teks individual. |
"NotSupported" |
Penyedia TextPattern dokumen tidak melaporkan atribut ini. Periksa dukungan aksesibilitas aplikasi. |
"Unavailable" |
Elemen tidak memiliki TextPattern. Gunakan inspect atau search untuk menemukan elemen teks/dokumennya. |
Saat mencantumkan semua properti, properti dasar yang di-cache tetap tersedia jika tidak ada elemen langsung yang dapat diselesaikan, dan nilai pemformatan cacat dihilangkan tanpa membuang properti lain. Kelalaian ini dicatat sebagai peringatan. Minta properti pemformatan tertentu untuk mendapatkan kesalahan alih-alih kelalaian.
Kegagalan penyedia tetap kesalahan, bukan "Unavailable". Untuk stale_element, periksa aplikasi lagi dan coba lagi dengan pemilih saat ini.
Amplop JSON mencakup elementId, bernilai string , dan bernilai elementpropertiesstring .
Properti yang ada, termasuk BoundingRectangle, pertahankan formatnya.
Misalnya, bagian pemformatan adalah properties :
{
"FontWeight": "700"
}
cuplikan layar
Ambil jendela atau elemen sebagai 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)
Tanpa pemilih elemen, pengambilan default menggabungkan beberapa jendela menjadi satu PNG komposit berlabel berdampingan, bukan file terpisah.
-a menurut nama proses atau PID mencakup jendela aplikasi dan jendela miliknya. Kecocokan berbasis -a judul memilih satu jendela yang cocok ditambah jendela yang dimilikinya; -w secara eksplisit memilih satu jendela ditambah jendela yang dimilikinya, tidak setiap jendela dalam proses. Oleh karena itu, dialog atau tipsalat yang dimiliki dapat muncul sebagai panelnya sendiri bahkan ketika Anda secara eksplisit memilih HWND utama. Pemilih elemen dipangkas ke elemen tersebut alih-alih menyusun jendela.
--quiet menekan output informasi untuk tangkapan satu jendela dan komposit, termasuk jalur yang disimpan. Peringatan dan diagnostik kegagalan pengambilan tetap terlihat. Gunakan --json sebagai gantinya saat Anda memerlukan jalur file dan dimensi sebagai output terstruktur.
Dengan --on sandbox, --output memberi nama tujuan host. Output biasa yang berhasil dan --json melaporkan bahwa jalur host setelah gambar dikirimkan.
Jalur pengambilan default menggunakan Windows. Graphics.Capture (WGC), membaca permukaan Aktual yang terdiri dari DWM — mempertahankan sudut bulat, transparansi, dan bekerja bahkan saat jendela dihilangkan oleh windows lainnya. Jika WGC tidak tersedia (build Windows yang lebih lama) CLI akan kembali ke PrintWindow.
Gunakan --capture-screen -w <hwnd> saat Anda memerlukan popup atau tipsalat yang terlihat di posisi layarnya, termasuk overlay yang tidak dimiliki oleh jendela target. Ini membaca wilayah layar jendela tersebut daripada menyusun panel berlabel, dan membawa jendela ke latar depan terlebih dahulu. Dengan -a, diperlukan tepat satu jendela yang cocok; jika beberapa jendela tingkat atas atau yang dimiliki cocok, gunakan winapp ui list-windows -a <app> dan coba lagi dengan -w <hwnd>. Gunakan --focus jika Anda hanya ingin memajukan jendela tanpa beralih mode pengambilan (misalnya, untuk memastikan cuplikan layar cocok dengan apa yang saat ini dilihat pengguna).
Karena DC layar menangkap apa pun yang sebenarnya ada di depan,
--capture-screenmemverifikasi target mencapai latar depan segera sebelum menangkap dan gagal denganforeground_not_targetjika tidak (pencegahan pencurian fokus, prompt UAC, atau jendela lain yang mengaktifkan dirinya sendiri). Tidak ada gambar yang ditulis dalam kasus itu — sebelumnya perintah keluar 0 dan menyerahkan kembali gambar jendela yang salah.ui record --capture-screenmenerapkan pemeriksaan yang sama sebelum bingkai pertama.
rekaman
Rekam jendela atau wilayah elemen ke H.264 MP4. Lebih suka positif --duration-sec untuk skrip tanpa pengawas. Tanpa durasi, perekaman berlanjut hingga Ctrl+C atau, untuk stdin yang dialihkan, baris baru atau EOF. Npm uiRecord dan targetRecord pembantu memerlukan bilangan bulat durationSec dari 1 hingga 86400; sinyal pembatalan mereka dibatalkan secara paksa daripada menyelesaikan rekaman dengan anggun.
# 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
Opsi:
-
--duration-sec N— Rekam selama N detik. Default 0 rekaman hingga dihentikan. -
--fps N— Bingkai target per detik (default 15). -
--max-edge N— Downscale sehingga tepi terpanjang paling banyak N piksel (0 = tanpa downscale). -
--capture-screen— Ambil dari layar DC (termasuk overlay/popup; latar depan jendela). -
--output <path>— Jalur MP4 output. Secara default menjadirecording-<timestamp>-<guid>.mp4. -
--overwrite— Ganti output rekaman yang ada setelah proses baru selesai. Tanpa itu, output yang ada ditolak. -
--frames— Tulis bukti JPEG bertanda waktu ke<output-name>.frames. Mendukung 1-30 fps dan--max-edge64-4096 (default 1280). Data bingkai dibatasi pada 1 GiB; MP4 berlanjut jika batas tercapai.
Artefak bingkai yang dapat dibaca agen:
evidence.mp4
evidence.frames/
manifest.json
frames.ndjson
frames/
frame-000000-t000000000012.jpg
frames.ndjson memiliki satu baris per sampel dengan sampleIndex, monotonik elapsedMs, MP4-relatif mediaTimeMs, imageIndex, file, dan changed. Sampel identik piksel berturut-turut menggunakan kembali JPEG kualitas-85 sebelumnya.
manifest.json merekam permintaan, waktu, status MP4, dimensi gambar, dan status (complete, partial, atau truncated). Waktu terpotong mencakup awalan yang dipertahankan, sementara video menjelaskan MP4 lengkap.
Pilih jalur output baru kecuali Anda ingin mengganti rekaman dengan --overwrite.
Tanpa itu, baik video yang ada atau direktori yang dipasangkan .frames memblokir perekaman, bahkan ketika Anda menghilangkan --frames.
MP4 sebelumnya tetap utuh jika penangkapan baru gagal. Pada penggantian yang berhasil, direktori bingkai sebelumnya dipertahankan sebagai <output-name>.frames.previous-<id>, bahkan jika rekaman baru menghilangkan --frames. Pertahankan bukti parsial dan ikuti yang dilaporkan recoveryHint sebelum mencoba kembali. Jika finalisasi MP4 gagal, bingkai yang dipertahankan dapat diterbitkan di bawah <output-name>.frames.partial-*. Artefak bingkai berisi konten layar yang tidak terenkripsi; menanganinya seperti cuplikan layar atau video.
Dengan --on sandbox, baik MP4 maupun direktori bingkai dikirimkan ke host, termasuk output default saat --output dihilangkan. Lihat Pengambilan sandbox untuk rekaman yang terganggu dan pengambilan seluruh desktop.
Mode pengambilan (dilaporkan di bidang JSON mode ):
-
wgc— Windows Graphics Capture (default; berfungsi saat jendela dikoreksi). -
printwindow— GDI PrintWindow (fallback ketika WGC tidak tersedia pada sistem/sesi ini; jalankan kembali dengan--capture-screenuntuk menggunakan DC layar sebagai gantinya). -
screen— Layar DC melalui--capture-screen(termasuk overlay/popup; membawa jendela ke latar depan).
Output JSON (--json):
-
stdout: Hasil rekaman akhir, termasuk irama, alasan berhenti, opsional
frameArtifacts, dan peringatan. -
stderr: Satu objek JSON per baris:
recording-startedperistiwa setelah bingkai pertama, diikuti oleh kesalahan jika perekaman nanti gagal. Jalur bingkai hanya disertakan ketika output bingkai aktif.
Kode kesalahan:
-
element_not_found— Pemilih tidak cocok. -
ambiguous_selector— Pemilih cocok dengan beberapa elemen; gunakan simpul yang disarankan. -
invalid_arguments— Nilai opsi tidak valid. -
output_exists— Output rekaman sudah ada dan tidak dapat diganti di bawah opsi yang diminta. -
frame_output_failed— Artefak tidak dapat dipertahankan setelah output bingkai gagal. -
partial_output— Hanya satu artefak yang selesai; inspeksipartialOutputdanrecoveryHint.
Batasan yang diketahui: Merekam elemen di dalam popup berjendela dapat menangkap jendela yang mendasar. Rekam seluruh jendela atau ikuti alur kerja overlay cuplikan layar untuk gambar diam. Lihat #646.
Memohon
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 SubmitButton -a myapp
Gunakan --action saat pengujian harus melakukan operasi tertentu pada elemen yang dipilih. Ini tidak pernah mencoba pola lain atau leluhur yang dapat dipanggil, bahkan jika tindakan yang diminta gagal. Kontrol yang mendukung pemanggilan dan pemilihan akan dipilih, tidak dipanggil, dengan --action select. Dengan --action, simpul menargetkan tepat satu elemen; pemilih teks biasa atau AutomationId yang cocok dengan lebih dari satu elemen gagal ditutup dengan kode keluar bukan nol daripada bertindak pada kecocokan pertama, jadi berikan simpul dari inspect/search ketika nama ambigu.
| Action | Operation |
|---|---|
invoke |
InvokePattern.Invoke |
select |
SelectionItemPattern.Select |
toggle |
TogglePattern.Toggle, tepat sekali |
toggle-on / toggle-off |
Baca ToggleState; berhasil tanpa mengubah status yang sudah benar, jika tidak, alihkan dan verifikasi |
expand / collapse |
ExpandCollapsePattern.Expand / Collapse |
Untuk toggle-on dan toggle-off, status awal Indeterminate memungkinkan paling banyak dua transisi, memeriksa status setelah masing-masing. Status awal lainnya memungkinkan satu transisi. Jika status yang diminta tidak tercapai, perintah gagal daripada terus beralih. Verifikasi yang gagal dapat membuat kontrol berubah; baca ToggleState sebelum memutuskan apa yang harus dilakukan selanjutnya.
Tanpa --action, perilaku otomatis yang ada tidak berubah: coba InvokePattern, TogglePattern, SelectionItemPattern, lalu ExpandCollapsePattern (perluas), dengan coba lagi invokable-ancestor saat diperlukan.
Tindakan yang tidak didukung gagal dengan kode keluar bukan nol dan, dengan --json, kesalahan terstruktur pada stderr. Periksa kontrol yang dipilih dan pilih tindakan yang didukungnya, atau targetkan induk yang dimaksudkan secara eksplisit. JSON berhasil mencakup requestedAction dan performedAction; lihat referensi JSON.
klik
Klik elemen di koordinat layarnya menggunakan simulasi mouse. Gunakan ini untuk kontrol yang tidak mendukung InvokePattern (misalnya, header kolom, item daftar).
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
Seperti kata kerja input-menyuntikkan lainnya,
clickmembawa target ke latar depan dan gagal dengan cepat (no_interactive_desktoppada desktop terkunci/aman,foreground_not_targetjika fokus tidak dapat ditransfer) daripada mengklik jendela yang salah. Ini juga menyelesaikan kembali elemen tepat sebelum tombol-turun: setelah memosisikan kursor, itu melakukan satu pemeriksaan posisi akhir, sehingga target yang terus bergerak/animasi gagal dengantarget_movedalih-alih melaporkan keberhasilan setelah klik mendarat di ruang kosong - keberhasilan yang dilaporkan berarti target masih ada ketika tombol turun.
seret
Tekan tombol mouse pada satu titik, pindahkan ke titik lain, lalu lepaskan dengan drag <from> <to>, di mana setiap titik akhir adalah pemilih elemen (menyeret dari/ke tengah elemen) atau koordinat x,ylayar persis seperti yang dilaporkan oleh winapp ui inspect. Campur dan cocokkan dengan bebas (pemilih→selektor, pemilih→koord, koord→koord).
SendInput Menggunakan dengan perpindahan menengah sehingga aplikasi melihat aliran WM_MOUSEMOVE pesan yang realistis. Gunakan untuk menyusun ulang/mengubah ukuran handel, penggeser, menggambar kanvas, dan seret dan letakkan.
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
Opsi:
-
--right— Seret dengan tombol kanan mouse alih-alih tombol kiri. -
--hold-ms <ms>— Tahan tombol di awal sebelum bergerak (default: 0). Dengan<from> == <to>(tidak ada gerakan) ini melakukan gerakan tekan-dan-tahan/ tekan panjang . -
--dwell-ms <ms>— Tinggal di tujuan setelah pindah, sebelum merilis (default: 0). Mari kita hilangkan target/ gabungkan overlay yang lengan dari hover berkelanjutan (daripada saat kursor tiba) kait sebelum tombol-up.
Bare
x,yadalah koordinat layar dalam laporan ruangwinapp ui inspect/searchyang sama, dan pemilih menyelesaikan ke pusat elemen — periksa terlebih dahulu untuk memilih titik.
Seperti
send-keys --via send-input,dragmenyuntikkan koordinat di seluruh OS di layar setelah membawa target ke latar depan. Jika fokus tidak dapat dibawa ke target (misalnya pencegahan pencurian fokus dari proses latar belakang), perintah gagal (foreground_not_target) daripada menyeret di jendela yang salah — fokus atau klik jendela terlebih dahulu. Pada desktop terkunci/aman, desktop gagal denganno_interactive_desktop. Setiap titik akhir elemen diselesaikan kembali segera sebelum seret; jika masih bergerak/mengubah ukuran (target animasi), perintah gagal dengantarget_movedalih-alih menyeret ke titik kedaluarsa. (Titik akhir barex,ytidak dapat diverifikasi ulang, sehingga digunakan as-is.)
Sentuh
Suntikkan gerakan sentuh sintetis menggunakan API Windows pointer-injection. Jangkar kontak adalah pemilih elemen (menggunakan pusat elemen) atau koordinat x,ylayar eksplisit melalui --at (laporan ruang winapp ui inspect yang sama). Gunakan untuk mengetuk/menekan interaksi dan gerakan multi-sentuh yang tidak dapat diekspresikan oleh simulasi mouse.
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)
Opsi:
-
--gesture <g>—tap(default),double-tap, ,long-pressswipe,pinch,stretch. -
--at <x,y>— Titik awal eksplisit (koordinat layar). Default ke pusat elemen pemilih. -
--to-point <x,y>— Titik akhir untukswipe. Lebih diutamakan daripada--direction. -
--direction <right|left|up|down>— Arah gesek (default:right). Dikombinasikan dengan--distanceuntuk menghitung titik akhir ketika--to-pointtidak diberikan. -
--distance <px>— Penyebaran jari untukpinch/stretch, atau gesek jarak dalam piksel. -
--hold-ms <ms>— Tahan kontak sebelum mengangkat (waktu penahanan tekan lama; default ke 500 ms saatlong-presstidak diatur). -
--duration-ms <ms>— Meluncurkan waktu untuk gerakan bergerak (gesek/jepit/regangkan; default 300). -
--fingers <n>— Jumlah kontak (1–10; default 1).pinch/stretchselalu gunakan 2.
Keamanan injeksi.
touchmenolak untuk menyuntikkan kecuali handel jendela target bukan nol diselesaikan dan jendela tersebut menahan latar depan — gagal ketikano_targettidak ada jendela yang dapat diselesaikan,foreground_not_targetjika fokus tidak dapat ditransfer, atauno_interactive_desktoppada desktop terkunci/aman. Setiap koordinat (pusat elemen, eksplisit--at/--to-point, dan titik arah yang dihasilkan) diperiksa terhadap persegi panjang jendela target; titik di luar jendela muncul sebagai peringatan non-fatal (warnings[]entri dalam , atau baris peringatan dalam--jsonmode teks) dan injeksi masih berlanjut - mencocokkan kata kerja mouse (click/drag/hover/scroll), yang juga menyuntikkan koordinat di luar jendela.--fingersdi atas 10 ditolak di muka.Catatan perangkat keras. Sentuh lebih suka perangkat penunjuk sintetis modern (
CreateSyntheticPointerDevice(PT_TOUCH)) dan kembali ke API warisanInitializeTouchInjection/InjectTouchInput. Jika injeksi tidak didukung pada perangkat/sesi saat ini, perintah menampilkan kode kesalahan Win32 yang sebenarnya (misalnya "tidak didukung") daripada melaporkan keberhasilan palsu — perlakukan pintu keluar bukan nol sebagai "sentuhan tidak terkirim".sesi Desktop Jauh /VM. Dalam Desktop Jauh (RDP) atau beberapa sesi VM, OS dapat menerima sentuhan sintetis (keluar 0) tanpa benar-benar mencapai aplikasi target. Saat sesi jarak jauh terdeteksi,
touchmenambahkan peringatan ketidakpastian pengiriman —warnings[]entri di--json, atau baris peringatan dalam mode teks. ✅Sebuah /exit 0 kemudian berarti panggilan injeksi berhasil, bukan berarti aplikasi menerima input; mengonfirmasi efeknya denganui screenshot/ui inspectkapan itu penting.
pena
Masukkan input pena/stylus sintetis — ketukan dan goresan tinta — menggunakan API penunjuk sintetis Windows (CreateSyntheticPointerDevice(PT_PEN); Windows 10 1809+). Targetkan pusat elemen, titik eksplisit --at , atau goresan tinta penuh --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
Opsi:
-
--at <x,y>— Titik kontak pena (koordinat layar). Default ke pusat elemen pemilih. Diabaikan ketika--pathdiberikan. -
--path "<x,y x,y …>"— Jalur goresan tinta sebagai pasangan yang dipisahkanx,yspasi putih (jalur satu titik adalah ketukan). -
--pressure <0.0–1.0>— Tekanan pena (default 0,5). -
--tilt-x <deg>/--tilt-y <deg>— Sudut miring pena, −90 hingga 90 (default 0). -
--eraser— Gunakan ujung penghapus pena alih-alih tip. -
--duration-ms <ms>— Total waktu perjalanan goresan dalam milidetik yang didistribusikan sebagai bingkai PEMBARUAN terinterpolasi di seluruh jalur (default: ~10 ms per titik arah). Gunakan ini untuk mengontrol seberapa cepat pena bergerak dari awal hingga akhir.
Keamanan injeksi. Seperti
touch,penmenolak untuk menyuntikkan tanpa jendela target non-nol, latar depan (no_target/foreground_not_target/no_interactive_desktop) dan memeriksa setiap titik tinta terhadap persegi panjang jendela target, memunculkan koordinat di luar jendela sebagai peringatan non-fatal (warnings[]dalam--json, atau garis peringatan dalam mode teks) saat masih menyuntikkan — konsisten dengan kata kerja mouse. Tidak valid--pressure(di luar 0,0–1,0) atau kempis (di luar ±90°) ditolak di depan.sesi Desktop Jauh /VM. Perutean pena sangat tidak dapat diandalkan melalui Desktop Jauh: panggilan injeksi dapat melaporkan keberhasilan (keluar 0) sementara tidak ada input pena yang mencapai aplikasi. Ketika sesi jarak jauh terdeteksi,
penmenambahkan peringatan ketidakpastian pengiriman (warnings[]dalam--json, atau baris peringatan dalam mode teks) sehingga tidak salah untuk pengiriman yang ✅ dikonfirmasi. Validasi alur dependen pena pada desktop interaktif lokal.
Hover
Pindahkan mouse ke tengah elemen untuk memicu efek hover (tipsalat, flyout, status visual).
SendInput Menggunakan untuk gerakan mouse realistis dengan wiggle kecil, lalu menunggu waktu tinggal yang dapat dikonfigurasi.
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
Opsi:
-
--dwell-time <ms>— Waktu dalam milidetik untuk menunggu setelah melayang agar efek muncul (default: 800, rentang: 0–10000)
send-keys
Kirim input keyboard sintetis — rekan keyboard ke click. UIA tidak memiliki pola injeksi keyboard, jadi ini turun ke lapisan Win32. Gunakan untuk navigasi keyboard (panah, Tab, Enter, Esc), pintasan (ctrl+c, alt+f4), dan mengetik ke dalam kontrol yang memerlukan peristiwa per tombol daripada set-value's atomic write.
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
Tata bahasa kunci (token yang dipisahkan spasi putih, string multi-token kutip):
-
Kunci bernama —
enter/return, ,tabesc/escape,space,backspace, ,delete/delinsert,home,end,pageup/pgup, ,pagedown/pgdn,up/down/left/right,f1–f16,apps,printscreen, .capslock -
Urutan — beberapa token ditekan secara berurutan:
down down enter. -
Kombo pengubah —
ctrl,shift,alt,windigabungkan dengan+:ctrl+shift+t,alt+f4. -
Teks literal — token apa pun yang bukan kunci yang diketahui diketik karakter berdasarkan karakter:
hello. Kata harfiah yang berdekatan menyimpan ruang di antara mereka, sehingga frasa yang dikutip seperti"Hello world"diketik verbatim (ruang dipertahankan); harfiah yang hanya berisi+sepertiC++ataua+bdiketik sebagai teks, tidak diurai sebagai kombo. -
Escape harfiah eksplisit — awali token dengan
text=untuk mengetikkannya verbatim bahkan ketika bertabrakan dengan nama kunci atau pengubah:text=enterketik kata "enter" alih-alih menekan Enter, dantext=ctrl+aketik string harfiah. Mencerminkanvk=escape; nilai escape masih bersatu dengan kata-kata harfiah yang berdekatan (text=down low→ "turun rendah"). Karena token adalah whitespace-split (dan literal yang berdekatan bergabung kembali dengan satu spasi), gunakan escape garis miring terbalik di dalamtext=nilai untuk mengetik spasi kosong yang tidak akan bertahan:\s→ spasi,\ttab →,\n→ garis baru,\r→ garis miring baru,\\→ garis miring terbalik harfiah.\n,\r, dan\r\nmasing-masing menyisipkan hentian baris tunggal (Enter /VK_RETURN), jaditext=line1\nline2dantext=line1\r\nline2keduanya ketik satu baris baru. Jaditext=a\s\sb, ketik "a b" (spasi ganda), dantext=\shimempertahankan ruang di depan. Escape yang tidak dikenal (misalnya\x) adalah verbatim kiri. -
Literal seluruh argumen (
--verbatim) — ketika seluruh payload adalah teks literal, teruskan--verbatimalih-alih melarikan diri setiap token dengantext=. Ini mengetik seluruh argumen kunci persis seperti yang diberikan — tidak ada interpretasi named-key/combo/vk=/text=— dan, tidak seperti jalur normal, mempertahankan spasi kosong internal yang tepat (tidak ada penciutan) tanpa memerlukan .\sJadisend-keys "down down enter" --verbatimketik kata-kata, dansend-keys "a b" --verbatimmenyimpan spasi ganda. Escape garis miring terbalik tidak didekodekan dalam--verbatimmode (\sdiketik sebagai garis miring terbalik dan "s"); gunakantext=token saat Anda memerlukan karakter kontrol yang lolos. -
Kunci virtual mentah —
vk=0xNN(hex) atauvk=NN(desimal) untuk kunci tanpa nama yang mudah diingat.
Opsi:
-
--target <selector>— Fokuskan elemen ini (melalui UIA) sebelum mengirim kunci. Tanpa itu, kunci masuk ke elemen aplikasi yang saat ini berfokus. -
--verbatim— Ketik seluruh argumen kunci sebagai teks harfiah (tanpa kunci/kombo/vk=/text=penguraian) dan pertahankan spasi kosong yang tepat. Bentuk seluruh argumen dari escape per tokentext=. -
--via <transport>—post-message(default) mempostingWM_KEYDOWN/WM_KEYUP/WM_CHARke antrean jendela target. Ini adalah UIPI yang ditargetkan HWND dan melewati (bekerja di seluruh tingkat integritas).send-inputmenyuntikkan os-wide melaluiSendInputdan pergi ke jendela latar depan.
Memilih batas transportasi/yang diketahui:
-
post-messageadalah default karena melewati UIPI dan tidak bergantung pada jendela latar depan. Batas: ini tidak dapat memicu hotkey global yang terdaftar melaluiWH_KEYBOARD_LLkait tingkat rendah (input ketukan upstream dari antrean jendela apa pun), dan aplikasi yang membaca status kunci mentah melaluiGetAsyncKeyStatemungkin tidak mengamati pengubah yang dipegang. Ini secara otomatis menyelesaikan dan memposting ke jendela anak yang berfokus pada utas target (melaluiGetGUIThreadInfo) setelah latar depan, sehingga aplikasi Win32/WinForms klasik yang kontrolnya adalah kunci penerima jendela anak terpisah tanpa menargetkan kontrol secara manual. Aplikasi WinUI 3 / UWP memiliki kontrol XAML tanpa jendela tanpa HWND anak, sehingga yang dipostingWM_CHAR/WM_KEYDOWNtidak memiliki apa pun untuk mendarat dan dihilangkan - pasca-pesan tidak dapat mendorongnya (perintah memperingatkan dan keluar 0); gunakan .--via send-input(WPF jendela adalah HWND tunggal dan kunci rute ke elemen yang berfokus pada internal, sehingga pasca-pesan berfungsi di sana.) -
send-inputmenghasilkan input yang sepenuhnya nyata (pengubah yang terlihatGetAsyncKeyStateoleh , menembakkan kait tingkat rendah) tetapi pergi ke jendela apa pun yang latar depan dan diblokir oleh UIPI saat menyuntikkan dari proses yang ditinggikan ke target integritas yang lebih rendah (AppContainer/AppX). Jikasend-inputmelaporkan kegagalan, target kemungkinan ditinggikan atau aplikasi AppX — gunakanpost-message, atau jalankan CLI pada tingkat integritas yang cocok. Sebagai penjaga keamanan,send-inputmemverifikasi jendela target sebenarnya berada di latar depan segera sebelum menyuntikkan dan gagal (foreground_not_target) daripada mengetik ke jendela yang salah jika fokus tidak dapat dibawa ke jendela tersebut — fokus atau klik jendela terlebih dahulu. Pada desktop terkunci atau aman gagal denganno_interactive_desktop(tidak ada jendela latar depan yang disuntikkan) — buka kunci sesi, atau gunakan kata kerja pola UIA (set-value,invoke). -
Combo yang dicadangkan sistem (
win+l, ,win+r,ctrl+shift+escctrl+alt+del,alt+tab,alt+f4,ctrl+esclonewin/printscreen, ...) bertindak pada OS/shell daripada hanya target saat dikirim di seluruh OS.send-inputmenolaknya secara default (kesalahan denganinvalid_argumentsdan tidak mengirim apa-apa) karena menyuntikkannya di tingkat OS memiliki efek jauh di luar jendela target (misalnyawin+lakan mengunci sesi). Teruskan--allow-system-keysuntuk ikut serta - ini memungkinkan Anda mendorong hotkey global seperti PowerToys'win+shift+vatauwin+r(kait tingkat rendah global menonton aliran input di seluruh OS, sehingga kombo yang disuntikkan menembakkannya). Pengecualian yang tetap diblokir bahkan dengan--allow-system-keys:win+lmengunci stasiun kerja yangLockWorkStation()tidak dapat dipulihkan dari otomatisasi (memutus sesi CI dan desktop jarak jauh), danctrl+alt+delmerupakan Secure Attention Sequence (SAS) yang Windows turun dari input yang disuntikkan terlepas dari bendera — tidak pernah dapat berlaku, sehingga kesalahan (invalid_arguments, keluar 1) alih-alih melaporkan keberhasilan yang menyesatkan. Kombo lain (alt+f4,ctrl+shift+esc, ,win+r...) diizinkan dengan bendera — pemanggil berhati-hatilah. Atau, untuk mengirimkan kombo sistem ke penggunaan--via post-messagejendela tertentu , yang tercakup dalam jendela dan tidak terpengaruh (yang dipostingwin+ltidak berbahaya, meskipun yang dipostingalt+f4masih menutup jendela target).
Peristiwa per-keystroke (KeyDown / TextChanged):
-
Kunci bernama dan kombo pengubah (
down,enter,ctrl+shift+t,vk=0xNN) menembakkan nyataKeyDown(danKeyUp) pada kedua transportasi — mereka dikirimkan sebagai peristiwa diskritWM_KEYDOWN/WM_KEYUP(atauSendInputkunci virtual). -
Teks yang dititik harfiah (
hello) berbeda menurut transportasi:-
--via send-inputmemetakan setiap karakter ke tombol virtualnya (plus Shift) pada tata letak keyboard aktif, sehingga target melihat karakter asliKeyDowndengan tombol virtual yang benar diikuti oleh yang disusun OS (menaikkanWM_CHARTextChanged) — yaitu satu penekanan tombol penuh per karakter. Karakter tidak dapat dijangkau pada tata letak saat ini (atau membutuhkan Ctrl/AltGr) kembali ke paket Unicode sehingga karakter yang tepat masih mendarat. Gunakansend-inputsaat Anda membutuhkan keakuratan per-keystrokeKeyDown(misalnya mengendarai WinUI 3 / WPFTextBoxyang kunci handler-nya matiKeyDown). Untuk host uji WinUI 3 normal (non-elevated), bawa jendelanya ke latar depan terlebih dahulu (winapp ui focus/ klik) karenasend-inputmenargetkan jendela latar depan. -
--via post-messagememposting satuWM_CHARper karakter ( tidak mempostingWM_KEYDOWN/WM_KEYUPuntuk teks yang diekstrak — yang dicadangkan untuk kunci/kombo bernama), yang tidak menaikkan per karakterKeyDown. Ini secara otomatis ditargetkan ulang ke kontrol anak yang berfokus pada jendela, sehingga kontrol edit klasik Win32/WinFormsWM_CHAR-driven mendaratkan teks (menaikkanTextChanged). Peringatan: Aplikasi WinUI 3 / UWP / XAML (target utama winapp) memiliki kontrol tanpa jendela yang diabaikan dipostingWM_CHAR/WM_KEYDOWN— jadi teks harfiah atau kunci bernama (Enter, digit, ...) mencapainya, meskipun perintah melaporkan keberhasilan. Ini memancarkan peringatan ketika target terlihat seperti XAML dan masih keluar 0 (PostMessageadalah fire-and-forget dan tidak dapat mengonfirmasi pengiriman). Gunakan--via send-inputuntuk mendorong aplikasi WinUI 3 / UWP / WPF; cadanganpost-messageuntuk kontrol Win32 klasik atau ketika Anda hanya membutuhkannya dalam cakupan jendela di seluruh tingkat integritas.
-
Output JSON (--json): hasilnya hwnd adalah jendela efektif tempat kunci dikirimkan — untuk --via post-message ini adalah kontrol anak terfokus yang diselesaikan ketika perintah ditargetkan ulang (belum tentu jendela tingkat -w/-a/-e atas), sehingga otomatisasi dapat mengonfirmasi dengan tepat di mana input mendarat. Ketika target efektif itu terlihat seperti host XAML tanpa jendela, peringatan pengiriman di atas juga muncul sebagai warnings[] entri (saran yang sama yang ditampilkan pada konsol), sehingga ✅ keluar 0 tidak keliru untuk pengiriman yang dikonfirmasi.
set-value
Tetapkan nilai pada elemen yang dapat diedit secara terprogram (tanpa penekanan tombol, tanpa latar depan aplikasi). Menggunakan rantai fallback:
- ValuePattern — TextBox, ComboBox, PasswordBox, dan kontrol yang paling dapat diedit.
- RangeValuePattern — kontrol numerik (Slider, ProgressBar) saat nilai diurai sebagai angka.
-
LegacyIAccessible (
IAccessible::put_accValue) — fallback untuk kontrol edit khusus TextPattern yang tidak mengekspos ValuePattern (misalnya kotak rich-edit /Documentcompose). Ini menutup celah baca/tulis di managet-valuebisa membaca kontrol seperti itu tetapiset-valuetidak bisa.
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
Jika tidak ada dari tiga pola yang dapat mengatur nilai, set-value gagal dengan kesalahan yang jelas yang menunjuk send-keys sebagai upaya terakhir.
Tidak setiap editor kaya mendukung set terprogram. Fallback LegacyIAccessible hanya berfungsi pada kontrol yang aksesibilitasnya mengimplementasikan
IAccessible::put_accValue— kontrol edit kaya Win32 asli dan permukaan kompos Chromium/Electron/WebView2 biasanya dilakukan. WinUI 3RichEditBoxdan WPFRichTextBoxtidak mendukung pengaturan nilai terprogram — secara desain mereka mengekspos konten mereka ke UI Automation sebagai baca-saja (Pola teks, tidak ada pola Nilai yang dapat diatur), sehinggaset-valuetidak dapat menulis kepada mereka. Gunakansend-keys(yang membutuhkan desktop latar depan yang tidak terkunci) untuk desktop tersebut.
get-value
Baca nilai saat ini dari elemen. Menggunakan rantai fallback cerdas: TextPattern (RichEditBox, Document) → ValuePattern (TextBox, Slider) → SelectionPattern (ComboBox, RadioButton, TabView) → Name (label).
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
Bidang teks kosong yang berhasil dibaca mengembalikan "text": "", bukan label aksesibilitasnya. Konten khusus spasi putih juga dipertahankan di JSON.
wait-for --value "" cocok dengan bidang kosong, apakah bidang tersebut segar atau dibersihkan setelah pengeditan. Untuk membaca label aksesibilitas, gunakan get-property --property Name.
Fokus
winapp ui focus txt-textbox-a4b1 -a notepad
Mengaktifkan jendela kontrol terpilih jika diperlukan, lalu memfokuskan kontrol.
Pemilih diperlukan; gunakan -a <app> atau -w <HWND> untuk memilih target.
Keberhasilan berarti jendela itu latar depan dan kontrol yang dipilih dikonfirmasi HasKeyboardFocus sebelum perintah dikembalikan. Perintah memungkinkan hingga 500 md agar kontrol melaporkan fokus; itu berhenti jika target menghilang atau kehilangan latar depan daripada mencoba mengambil fokus kembali. Dialog yang dimiliki di depan jendela utama tidak cukup: pilih kontrol dalam dialog jika itu adalah target Anda.
Perintah ini memerlukan desktop interaktif yang tidak terkunci dan tidak melewati batasan aktivasi Windows. Jika gagal dengan foreground_not_target, aktifkan jendela yang dimaksudkan secara manual dan periksa dialog pemblokiran sebelum mencoba kembali.
Untuk focus_not_acquired, periksa UI saat ini dan pilih kontrol yang dapat difokuskan.
Untuk stale_element, menemukan kembali target dengan inspect atau search.
Pertahankan target yang sama --on pada perintah penemuan dan coba lagi.
scroll-into-view
Gulir elemen ke area yang terlihat.
winapp ui scroll-into-view itm-targetitem-c3d4 -a myapp
tunggu-untuk
Tunggu hingga elemen muncul, menghilang, atau memiliki nilai mencapai target.
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
Gulir
Gulir elemen kontainer. Temukan kontainer yang dapat digulir dengan search scroll — cari [scroll:v] penanda (vertikal) atau [scroll:h] (horizontal).
# 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
Opsi:
-
--direction <up|down|left|right>— Gulir secara bertahap melaluiScrollPattern. -
--to <top|bottom>— Lompat ke awal/akhir melaluiScrollPattern. -
--wheel <notches>— Mensintesis input roda mouse di atas tengah elemen melaluiSendInput, dalam takik roda (penahanan):1= satu takik naik/menjauh,-1= satu takik ke bawah/ke arah,3= tiga takik ke atas. (Setiap notch adalah WindowsWHEEL_DELTA120 unit yangSendInputmengonsumsi; CLI menskalakan takik sebesar 120 untuk Anda.) MelewatiScrollPattern.
--direction,--to, dan--wheelsaling eksklusif — berikan tepat satu. Karena--wheelmenyuntikkan input di seluruh OS pada koordinat layar, itu membawa target ke latar depan terlebih dahulu dan gagal (foreground_not_target) jika fokus tidak dapat ditransfer, daripada menggulir jendela yang salah.
get-focused
winapp ui get-focused -a myapp
winapp ui get-focused -w <HWND> --json
Tampilkan elemen yang saat ini memiliki fokus keyboard di aplikasi yang dipilih, termasuk kontrol yang kepemilikan aplikasinya hanya tersedia melalui jendela induknya.
Dengan -w, fokus harus berada di jendela tersebut, bukan jendela lain atau popup yang dimiliki dalam proses yang sama. Dengan -a, jendela lain dalam proses yang dipilih disertakan.
Output JSON memiliki hasFocus:false ketika tidak ada elemen terfokus yang dapat diverifikasi sebagai milik target. Jika kueri fokus atau kepemilikan jendela gagal, perintah keluar dari bukan nol sebagai gantinya; coba get-focusedlagi , dan cari kembali jendela dengan list-windows jika telah ditutup.
list-windows
Mencantumkan semua jendela yang terlihat untuk aplikasi, termasuk popup dan dialog. Secara default, jendela tanpa judul dengan ukuran nol (jendela sistem yang tidak terlihat) dikecualikan.
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
hasil
Rilis UI alur kerja ini berubah lebih awal alih-alih menunggu tenggang menganggur empat detik.
WINAPP_UI_WORKFLOW_IDMemerlukan ; tidak mengambil aplikasi dan tidak ada pemilih. Lihat Melepaskan belokan lebih awal.
winapp ui yield
winapp ui yield --json # {"released": true} — or false when nothing was held
Dukungan Kerangka Kerja
| Kerangka kerja | Memeriksa | cari | Memohon | set-value | cuplikan layar |
|---|---|---|---|---|---|
| WPF | ✅ Pohon penuh | ✅ Semua properti | ✅ Semua pola | ✅ ¹ | ✅ |
| WinForms | ✅ | ✅ | ✅ | ✅ | ✅ |
| Win32 | ✅ | ✅ | ✅ | ✅ | ✅ |
| WinUI 3 | ✅ | ✅ | ✅ | ✅ ¹ | ✅ |
| Elektron | ⚠️ Pohon kromium | ⚠️ Terbatas | ⚠️ Bervariasi | ⚠️ Bervariasi | ✅ |
| Flutter | ⚠️ Dasar | ⚠️ Dasar | ❌ Minimal | ❌ | ✅ |
¹ set-value berfungsi pada kontrol apa pun yang mengekspos ValuePattern/RangeValuePattern, ditambah kontrol edit khusus TextPattern yang aksesibilitasnya mengimplementasikan IAccessible::put_accValue (fallback LegacyIAccessible).
WinUI 3 RichEditBox dan WPF RichTextBox adalah pengecualian — hanya mengekspos pola Teks baca-saja (tidak ada pola Nilai yang dapat diatur), sehingga tidak dapat diatur secara terprogram berdasarkan desain; gunakan send-keys (desktop interaktif diperlukan) untuk mengetiknya.
Menggunakan mesin dari kode Anda sendiri
Semuanya winapp ui tersedia sebagai pustaka, sehingga Anda dapat mendorong otomatisasi yang sama dari pengujian atau alat tanpa keluar ke CLI:
| Paket | Apa yang ditambahkannya |
|---|---|
Microsoft.Windows.SDK.BuildTools.WinApp.UIAutomation |
Inspeksi, pemilih, interaksi pola UIA, injeksi input, cuplikan layar |
Microsoft.Windows.SDK.BuildTools.WinApp.UIAutomation.Recording |
Perekaman video ke MP4, ditambah bundel bingkai |
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);
Untuk tindakan deterministik, gunakan pengambilan kelebihan beban 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 menolak teks ambigu alih-alih memilih kecocokan yang dapat dipanggil. Kecocokan AutomationId yang tepat lebih diutamakan daripada nama atau substring AutomationId; nama unik masih dapat memilih kontrol yang AutomationId-nya dibagikan.
Untuk target cakupan aplikasi, pemeriksaan tersebut mencakup semua jendela aplikasi/miliknya. Gunakan -w <HWND> (atau target pustaka jendela eksplisit) untuk membatasi cakupan pilihan.
Ini mengembalikan Pattern dan PerformedAction dengan arti yang sama dengan hasil tindakan CLI.
Berikan elemen yang dikembalikan oleh inspeksi atau pilihan, dengan simpul runtime atau AutomationId uniknya utuh. Tindakan eksplisit menolak identitas yang hilang atau ambigu daripada mengikat ulang berdasarkan nama dan jenis kontrol.
Untuk bacaan tercakup, atur UiSelector.Root ke lainnya UiSelector, ControlType ke nama jenis, dan ClassName ke kelas penyedia harfiah. Ini menggunakan predikat kueri yang sama dengan CLI. Hanya satu tingkat akar yang didukung: selector.Root.Root harus null. Akar berlapis melempar ArgumentException sebelum mencari jendela target. Gunakan AutomationId akar unik atau simpul alih-alih menumpuk pemilih akar.
UiControlTypes.GetId(name) menyelesaikan nama jenis resmi dan dua alias yang didokumenkan, mengembalikan 0 untuk nama yang tidak valid.
UiControlTypes.GetName(id) mengembalikan nama kanonis, atau Unknown(id) untuk ID yang tidak dikenal.
Saat meneruskan yang UiElement dipulihkan dari JSON ke GetTextAsync atau GetPropertiesAsync, simpan Selector dan WindowHandle. Pemilih simpul masih harus mengidentifikasi elemen asli; jika tidak ada lagi, bacaan ini dilemparkan UiElementNotFoundException alih-alih memilih elemen lain dengan AutomationId atau nama yang sama. Jalankan kueri asli lagi untuk merefresh hasilnya. Pembacaan tercakup juga menyebarkan kegagalan dari getter properti UIA umum dan memperoleh pola UIA daripada mengembalikan nilai null atau yang diambil sebelumnya.
Perekaman adalah paket terpisah sehingga proyek yang hanya memeriksa dan mendorong UI tidak menarik skiaSharp. Paket otomatisasi menargetkan dan net10.0-windowsnet10.0-windows10.0.19041.0; yang terakhir menambahkan Windows Graphics Capture, yang memungkinkan pengambilan windows yang dikomposisi screenshot GPU atau terkomposisi. Lihat README setiap paket di NuGet untuk API lengkap dan trade-off kerangka kerja target.
UiTarget.FromWindowHandleadalah titik masuk untuk kerangka kerja pengujian yang sudah memberi Anda jendela — misalnya MSTest.Windows.UIAutomation, yang merupakan UIA2 AutomationElement yang WindowTest.MainWindow Anda jembatani dengan MainWindow.Current.NativeWindowHandle.
Troubleshooting
| Kesalahan | Cause | Solution |
|---|---|---|
| "Tidak ada aplikasi yang berjalan yang ditemukan" | Aplikasi tidak berjalan atau nama tidak cocok | Periksa nama proses atau gunakan PID |
| "Beberapa jendela cocok" | Nilai ambigu -a |
Gunakan -w <HWND> dari opsi yang tercantum |
| "memiliki beberapa jendela" | Proses memiliki beberapa jendela | Gunakan -w <HWND> untuk menargetkan yang spesifik |
| "Pemilih cocok dengan elemen N" | Pemilih warisan ambigu | Gunakan simpul dari inspect output, atau tambahkan [0], [1] ke pemilih warisan |
| "Elemen mungkin telah berubah" | Hash simpul tidak cocok dengan elemen saat ini | Jalankan inspect kembali atau search untuk mendapatkan simpul segar |
| "tidak mendukung pola pemanggilan apa pun" | Elemen tidak dapat dipanggil | Gunakan inspect pada elemen untuk menemukan anak yang dapat dipanggil |
| "Tidak ada jendela UIA yang ditemukan" | UIA tidak dapat melihat prosesnya | Gunakan list-windows untuk menemukan HWND, lalu -w |
| "Jendela memiliki ukuran nol" | Jendela diminimalkan | Aplikasi akan dipulihkan secara otomatis |
| Popup/dropdown tidak ada di cuplikan layar | Pengambilan default adalah per jendela dan tidak menyertakan overlay yang tidak disetujui | Ikuti alur kerja overlay cuplikan layar untuk memilih jendela dengan -w <hwnd> --capture-screen |
foreground_not_target dari --capture-screen |
Windows menolak aktivasi, sehingga tangkapan layar akan merekam jendela apa pun yang sebenarnya ada di depan | Klik jendela target atau tutup jendela pencurian fokus dan coba lagi, atau letakkan --capture-screen |
element_not_found selama rekaman |
Pemilih diberikan tetapi tidak ada elemen yang cocok | Jalankan inspect kembali atau search untuk mendapatkan pemilih baru |
| WGC tidak tersedia selama rekaman | Init penangkapan WGC gagal; tidak ada fallback senyap | Periksa GPU/driver; gunakan --capture-screen untuk menyetujui pengambilan screen-DC |
Pola Umum
Menavigasi dan memverifikasi
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
Menemukan teks dan memanggil induknya
# 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
Elemen duplikat disambiguate
winapp ui search '#Image' -a myapp; winapp ui invoke itm-image-a2b3 -a myapp
Cuplikan layar dengan overlay popup
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
Menavigasi, menunggu, dan memverifikasi (rantai tunggal)
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
Menemukan, mengklik, dan memverifikasi
winapp ui inspect -a myapp --interactive; winapp ui invoke btn-submit-7a90 -a myapp; winapp ui screenshot -a myapp
Interaksi dialog file
Dialog buka/simpan file adalah dialog Windows standar dengan dukungan 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>
Gunakan inspect -w <dialog-hwnd> --interactive untuk menemukan siput aktual untuk dialog tertentu.
Mengapa ; untuk menautkan (bukan &&)
Operator PowerShell && dapat membeku saat CLI asli menulis ke stderr atau menggunakan urutan escape ANSI. Gunakan ; sebagai gantinya — menjalankan setiap perintah tanpa syarat dan menghindari kebuntuan ini. Ini juga lebih baik untuk alur kerja agen: Anda biasanya ingin cuplikan layar berjalan meskipun pemanggilan memiliki pintu keluar bukan nol.
Pola Pengujian CI
Gunakan perintah winapp ui dalam alur CI (GitHub Actions, Azure DevOps) untuk uji asap dan validasi UI.
wait-for dengan --property dan --value bertindak sebagai pernyataan - mengembalikan kode keluar 1 pada waktu habis, gagal langkah CI secara otomatis.
Luncurkan dan uji di 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
Menegaskan status elemen dengan wait-for
wait-for --value polling hingga nilai elemen cocok dengan string yang diharapkan, menggunakan fallback cerdas yang sama dengan get-value (TextPattern → ValuePattern → SelectionPattern → Name). Mengembalikan kode keluar 0 pada kecocokan, keluar dari kode 1 pada waktu habis — menjadikannya pernyataan ramah CI. Gunakan --property untuk memeriksa properti UIA tertentu sebagai gantinya.
# 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
Menegaskan dengan output JSON
Gunakan --json dengan PowerShell atau jq untuk pernyataan yang lebih kompleks:
Kontrak kode keluar untuk
searchdanwait-fordalam mode: ketika tidak ada elemen yang cocok () atau waktu tunggu habis (), perintah menulis amplop hasil yang sepenuhnya dapat diurai--jsonkesearch(wait-foratau ) dan mengembalikan{ "matchCount": 0, ... }.{ "found": false, "timedOut": true, ... }Stderr kosong dalam--jsonmode (output pencatat ditekan). Cabang pada bidang amplop, atau pada$LASTEXITCODE, tergantung pada mana yang lebih ergonomi.
# 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" }
Amplop JSON adalah:
-
inspect:{ "depth", "interactive", "hideDisabled", "hideOffscreen", "windows": [...] } -
search:{ "matchCount", "hasMore", "matches": [...] } -
wait-for:{ "found", "waitedMs", "element"?, "timedOut" } -
get-property:{ "elementId", "element", "properties": { ... } }
Elemen yang ditik menggunakan type dan numerik x, , y, width, dan height.
Geometri berada dalam piksel layar fisik.
0,0,0,0adalah persegi panjang UI kosong/tidak ditampilkan UI Automation dalam proyeksi ini; isOffscreen terpisah, sehingga elemen di luar layar masih dapat memiliki batas nonzero.
Setiap inspect --jsonwindows[] entri dan hasilnya status --json meliputi windowDpi, scale (windowDpi / 96), dpiAwareness, dan coordinateSpace: "physical-screen-pixels". Ini menjelaskan konteks DPI jendela target, bukan DPI monitor tanpa syarat: Windows melaporkan 96 untuk jendela yang tidak sadar, DPI sistem untuk jendela yang sadar sistem, dan DPI monitor saat ini untuk jendela yang sadar per monitor. Jika konteks HWND atau DPI tidak dapat dibaca, perintah gagal daripada menggantikan 96 secara diam-diam. Ketika status menyelesaikan proses sebelum memiliki jendela tingkat atas, hwnd adalah 0 dan bidang DPI dihilangkan hingga jendela ada. Untuk seluruh inspectproses , jendela target yang dipilih tetap gagal dengan cepat; jika popup selanjutnya menghilang setelah pohonnya dibaca, entrinya windows[] membawa dpiError dan menghilangkan bidang DPI sementara pohon jendela yang tersisa masih dikembalikan.
Lihat keterampilan references/ui-json-envelope.md yang dikirim winapp-ui-automation untuk contoh lengkap setiap amplop.
Contoh uji asap penuh
# 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