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, , searchget-property, get-value, wait-for, set-value, invoke, scroll --direction/--to, screenshot - mendorong aplikasi melalui pola UIA dan ramah tanpa kepala / sesi terkunci. 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
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. Hash memberikan deteksi kedaluarsa — jika elemen telah diganti, Anda mendapatkan: "Elemen mungkin telah berubah. Jalankan kembali inspeksi."
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
cuplikan layar
Ambil jendela atau elemen sebagai PNG. Ketika ada beberapa jendela (misalnya, dialog aplikasi + terbuka), jendela tersebut terdiri dari satu PNG dengan setiap jendela dijahit.
winapp ui screenshot -a notepad # saves screenshot.png in cwd
winapp ui screenshot -a notepad --output my.png # custom filename
winapp ui screenshot -a notepad --json # returns file path as JSON
winapp ui screenshot -w 131906 # target specific HWND (+ its dialogs)
winapp ui screenshot txt-searchbox-e5f6 -a myapp # crop to element bounds
winapp ui screenshot -a myapp --capture-screen # capture from screen (includes popups/overlays; foregrounds window)
winapp ui screenshot -a myapp --focus # bring window to foreground first, then capture (default WGC path)
Saat dialog atau popup terbuka, semua jendela terdiri dari satu PNG sehingga Anda dapat melihat status antarmuka pengguna lengkap dalam satu gambar.
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 saat Anda perlu mengambil menu popup, dropdown, flyout, atau overlay tipsalat yang tidak dimiliki oleh jendela target.
--capture-screen membaca dari layar DC dan membawa jendela ke latar depan terlebih dahulu. 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).
rekaman
Rekam jendela atau wilayah elemen ke H.264 MP4. Secara default, perekaman berlanjut hingga Ctrl+C atau, untuk stdin yang dialihkan, baris baru atau EOF.
# 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 demo.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. -
--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:
demo.mp4
demo.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.
Dengan --frames, jalur MP4 dan bingkai yang ada tidak diganti. Jika finalisasi MP4 gagal, bingkai yang dipertahankan diterbitkan di bawah <output-name>.frames.partial-*. Artefak bingkai berisi konten layar yang tidak terenkripsi; menanganinya seperti cuplikan layar atau video.
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— Dengan--frames, direktori MP4 atau bingkai sudah ada. -
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 gunakan ui screenshot --capture-screen. Lihat #646.
Aktifkan elemen secara terprogram (klik tombol, alihkan kotak centang, perluas kotak kombo).
winapp ui invoke btn-submit-7a90 -a myapp # by slug from inspect
winapp ui invoke btn-submit-a1b2 -a myapp # by slug from inspect/search
winapp ui invoke cmb-sizecombobox-b4c5 -a myapp # expand combo box
Pola percobaan secara berurutan: InvokePattern → TogglePattern → SelectionItemPattern → ExpandCollapsePattern.
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 hover btn-info-a1b2 -a myapp; winapp ui screenshot -a myapp --capture-screen # hover then capture tooltip
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": "..." }
Fokus
Pindahkan fokus keyboard ke elemen.
winapp ui focus txt-textbox-a4b1 -a notepad
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
Perlihatkan elemen yang saat ini memiliki fokus keyboard.
winapp ui get-focused -a myapp
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
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.
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 | Gunakan --capture-screen bendera |
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 set-value txt-searchbox-e5f6 "query" -a myapp; winapp ui screenshot -a myapp --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)" }
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