UI Otomasyonu

Komut satırından çalışan Windows uygulamaları inceleyin ve bunlarla etkileşime geçin. Yapay zeka aracıları ve geliştiriciler tarafından kullanıcı arabirimi testi, hata ayıklama ve otomasyon için kullanılır.

Genel bakış

winapp ui, Windows uygulama URI'lerini incelemeye ve bunlarla etkileşime başlamaya yönelik komutlar sağlar. Windows UI Otomasyonu (UIA) kullanır. WPF, WinForms, Win32, Electron ve WinUI 3 gibi tüm Windows uygulamalarıyla çalışır. Komutların çoğu uygulamayı UIA desenleri üzerinden yönlendirir (giriş ekleme yoktur). Özel durumlar gerçek giriş ekler: ui click/ui hover/ui dragUIA desenlerinin kullanabildiği denetimler ve senaryolar için fare benzetimiui touch/ui pen kullanın, ui send-keys dokunma ve kalem/ekran kalemi girişini sentezleyin ve klavye girişini sentezler.

Important

Etkileşimli masaüstü gereksinimi (giriş ekleme fiilleri).click, hover, drag, touch, penscroll --wheelve send-keys --via send-input işletim sistemi düzeyinde girişi sentezler, böylece ön planda hedef pencereye sahip kilitli olmayan, etkileşimli bir masaüstüne ihtiyaç duyarlar. Kilitli bir iş istasyonunda veya güvenli masaüstünde (LogonUI/UAC) ile no_interactive_desktop hızlı bir şekilde ekleyemez ve başarısız olamazlar (yükseltmeden/foreground_not_target durumlardan farklı). touch / penAyrıca, hiçbir pencere çözümlenmezse (no_target); hedef pencerenin dışındaki koordinat önemli olmayan bir uyarıdır (altında warnings[]bir --json giriş veya metin modunda bir uyarı satırı) ve ekleme işlemi devam eder ve fare fiilleriyle tutarlıdır. Diğer her şey ( inspect, search, get-property, get-value, , wait-for, set-value, , invoke), scroll --direction/--to uia desenleri aracılığıyla uygulamayı yönetir ve başsız/kilitli oturum dostudur. screenshot eklenmeyen fiiller arasındaki özel durumdur: özel bir dönüş alır ve altyapı simge durumuna küçültülmüş bir hedefi geri yüklediğinden ve çerçeve yakalama kullanılamadığında veya --capture-screen kullanıldığında ön plana geri düştüğünden, yakalama özelliği kullanılabilir bir etkileşimli masaüstüne ihtiyaç duyar. CI'de UIA desenli fiilleri tercih edin; gerçekten gerçek giriş gerektiren senaryolar için ekleme fiillerini ayırın. Eklemeden önce, hareket fiilleri de hedef öğeyi yeniden çözümler ve boş alana giriş yerine hala animasyonlu/yeniden konumlandırılıyorsa ile target_moved reddeder.

Hızlı Başlangıç

# Connect to any app and see its UI tree
winapp ui inspect -a notepad

# Find specific elements
winapp ui search Button -a notepad

# Activate an element
winapp ui invoke Close -a notepad

# Take a screenshot
winapp ui screenshot -a notepad

Windows Korumalı Alanında UI otomasyonlarını çalıştırma

Otomasyonu masaüstünüzden uzak tutmak için çalıştırma ve kullanıcı arabirimi komutlarına ekleyin --on sandbox :

winapp run . --on sandbox --detach
winapp ui inspect --on sandbox -a MyApp
winapp ui invoke --on sandbox SubmitButton -a MyApp

--detach başlatmadan sonra döndürür; olmadan, run uygulamanın çıkışını bekler. PID veya pencere tutamacını kullananlar da dahil olmak üzere her konuk komutunda tutun --on sandbox . İstemci gereksinimleri, kısa kurulum/yeniden bağlantı odak değişiklikleri, iş akışı koordinasyonu ve konak çıktı teslimi için korumalı alan yürütme Windows bakın.

Kapsamı belirlenmiş ve yazılan sorgular

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-property, get-valueve wait-for bu isteğe bağlı filtreleri kabul edin. Seçici ve sağlanan her filtre aynı öğeyle eşleşmelidir:

  • --root <selector> yalnızca benzersiz olarak eşleşen bir kökün alt öğelerini arar, hiçbir zaman kökün kendisini aramaz. AutomationId veya bilgi kümesinden inspect disambiguate'a kadar kullanın. Birden çok öğeyle eşleşen bir kök, bir eşleşme çağrılsa bile ile ambiguous_selectorbaşarısız olur. Eksik kök eşleşme üretmez. Kök bulunduktan sonra, alt öğe eşleşmediğinde bile sorgular ilgisiz açılır pencerelerde arama yapmaz. Sorgular görüntüleme derinliğiyle inspectsınırlı değildir.
  • --type <control-type> bir UIA denetim türüyle eşleşir, büyük/küçük harf yoksayılarak. Tek diğer adlar TextBox → Edit ve TextBlock → Text. Bilinmeyen adlar (sayısal kimlikler ve joker karakter ifadeleri dahil) ile invalid_argumentsbaşarısız olur.
  • --class-name <literal> , servis talebini yoksayarak sağlayıcının tüm UIA'sı ClassNameile eşleşir. Alt dize, joker karakter veya normal ifade değildir. Sağlayıcının değerini bulmak için kullanın get-property --property ClassName ; sınıf adının UIA denetim türüne eşit olması gerekmez.

Filtrelenmiş sorgular UIA'nın Denetim Görünümü'nü kullanır ve aynı görünüm tarafından inspectgösterilir. Yalnızca Ham Görünümde kullanıma sunulan sağlayıcı düğümleri döndürülmüyor; inspect öğesini kullanarak içeren denetimi ve seçicisini bulun.

41 resmi türün tümü desteklenir: Button, , , CheckBox, ComboBox, Edit, , Hyperlink, , ListImageMenuProgressBarRadioButtonScrollBarMenuItemMenuBarSliderListItem, , SpinnerStatusBar, TabItemToolBarTabTreeItemTreeToolTipText, Custom, GroupThumb, . AppBarHeaderItemTableHeaderTitleBarSeparatorDataGridDocumentSemanticZoomDataItemSplitButtonWindowPaneCalendar

wait-for kök seçiciyi her yoklamada yeniden çözümler, böylece kök komut başlatıldıktan sonra görünebilir. ile --gone, eksik kök eşleşen bir alt öğe olmadığı anlamına gelir; belirsiz kök bir hatadır, başarılı değildir. Kesintiye uğrayan arama kaybolma kanıtı değildir: Öğe arama sırasında kaldırılırsa veya okumadan önce değiştirilirse, sonraki --value yoklama yeniden denetler; diğer arama veya okuma hataları komutu başarısız olur. -w <HWND> , kök bulmayı bu pencerenin UIA ağacıyla kısıtlar. ile -akök bulma, uygulamanın açılır pencerelerini de bulabilir. Tam kök AutomationId eşleşmeleri, tüm bu pencerelerde alt dize eşleşmelerine göre önceliklidir; ile birden çok tam eşleşme başarısız olmaya devam ediyor ambiguous_selector.

Kök bilgi kümesi, başka bir pencere aynı AutomationId'ye sahip olsa bile bu öğeyi seçer. Seçilen kök değiştirilirse, eski bilgi artık eşleşmiyor; yoklamanın bir değiştirme işlemini izlemesini istediğinizde AutomationId veya ad kökü kullanın.

Filtreler mevcut olduğunda, birden fazla öğe kalırsa tek bir öğeyi okuyan komutlar başarısız olur ambiguous_selector ; filtreleri daraltın veya benzersiz bir bilgi kümesi kullanın. Tam AutomationId eşleşmeleri, filtrelenen kapsam içinde alt dize eşleşmelerine göre önceliği korur. Üç seçeneğin de atlanması, mevcut sorgu davranışını korur.

Eş zamanlı kullanıcı arabirimi iş akışlarını koordine etme

Windows yalnızca bir ön plan penceresi, bir klavye odağı, bir imleç ve bir giriş akışı vardır. İki winapp ui iş akışı aynı anda aynı oturum açmış masaüstünde çalıştırıldığında, birbirlerinden odağı çalabilir, yeni açılan menüyü kapatabilir veya bekleyen bir tıklamanın altından hedefi dışarı taşıyabilir.

Tahkim her zaman açık. Fiziksel masaüstüne dokunan her winapp ui komut, kurulum olmadan ve kapatmanın hiçbir yolu olmadan bir dönüş alır, böylece iki aracı birbirlerinin pencerelerine asla yazamaz. Salt okunur komutlar eşzamanlı olarak çalışmaya devam eder.

Komutlar arasındaki süreklilik kabul edilir. Varsayılan olarak her komut kendi içinde tek seferlik bir komutdur: sırasını bekler, çalışmasını yapar ve masaüstünü hemen serbest bırakır. Masaüstünü çeşitli komutlar arasında tutmak için tümüne aynı iş akışı kimliğini verin:

# Set once per logical UI workflow
$env:WINAPP_UI_WORKFLOW_ID = [guid]::NewGuid().ToString()

Bilmeniz gerekenler:

  • İş akışı kimliği tek bir mantıksal iş akışını adlandırabilir ; aracının tamamı ve tek bir uygulama olması gerekmez. İşbirliği komutları için aynı değeri kullanın (bir kayıt ve yakalaması gereken tıklamalar); bir aracı her ikisini de başlattığında bile bağımsız iş akışları için farklı değerler kullanın.
  • Kimlik olmadan, her komut bağımsız bir tek seferliktir. Yine de hakemlik yapar, ancak zarafeti bankaya atlar ve bittiğinde masaüstünü devre dışı bırakır. İki no-id komutu, aynı kabuktan başlatıldığında bile ayrı iş akışlarıdır.
  • Yeni kabuk ve uyarlamalı konaklar aynı değeri eklemelidir. Her komut yeni bir kabukta çalışıyorsa (çoğu aracı aracı çağrısı böyle çalışır), bunları gruplandırabilecek tek şey, işbirliği yapılan her çağrıya geçirilen açık WINAPP_UI_WORKFLOW_ID bir ifadedir.
  • Dört saniyelik zarafet, model mantâsını değil sıkı patlamaları korur. Kimliği olan bir iş akışı, sonraki komut dört saniye içinde başladığı sürece dönüşünü korur. Bu, bir betikteki arka arkaya komutları kapsar; model düşünürken kasıtlı olarak süresi dolar. Bu, tamam olduğunuzu söyleyemediğiniz zamanların geri dönüşüdür; mümkün olduğunda, beklemek yerine çalıştırın winapp ui yield .
  • Uyarlamalı iş akışları yeniden sorgulamalı, yeniden doğrulamalı ve yeniden yürütmelidir. Bir mantık boşluğundan sonra başka bir iş akışı masaüstünü kullanmış olabilir, bu nedenle menüyü yeniden açın, öğeyi yeniden çözün ve işlem yapın. Bilinen uçtan uca dizileri, düşünürken masaüstünü tutmak yerine sıkı bir betik olarak gönderin.
  • Sıralama, önce sahip benşimi, ardından diğerleri arasında FIFO'dur. Bir iş akışı etkin veya yetkisiz kullanımda olsa da, diğer iş akışları zaten bekliyor olsa bile komutların verilmesini sürdürebilir. Çalıştırıldığında winapp ui yield veya yetkisiz kullanım süresi dolduğunda, bekleyen iş akışları katı bir varış sırasına göre sunulur. Bu nedenle bir iş akışı tarafından yapılan sürekli etkinlik diğerlerini süresiz olarak geciktirebilir.
  • Sert şapka yok. Uzun bir betik, ilişkisiz kayıt veya hata döngüsü diğer sessize alınan iş akışlarını engelleyebilir.
  • İptal veya işlem sonlandırma, takılan bir canlı iş akışının kurtarılmasıdır . Bekleyen komutlar bir saniye sonra bir durum yazdırır ve ile Ctrl+Cdurdurulabilir ve komutundan çıkar 130.
  • Yalnızca uyumlu güncelleştirilmiş ikili dosyalar işbirliği sağlar. Eski winapp derlemeler bu özelliğin önceden tarihini alır ve eşgüdümlü değildir. UI Otomasyonu NuGet paketlerini çağıran kod bu garantinin tamamen dışındadır; koordinasyon paketlerde değil CLI'da bulunur.

Hangi komutlar dönüş bekler:

Davranış Commands
Eşzamanlı olarak çalışır (hiçbir zaman beklemez) status, list-windows, inspect, , search, get-property, get-value, get-focused, wait-for
Sırayı bekler ama masaüstünü asla almaz set-value, scroll-into-view, scroll --direction/--to, record
Sırayı bekler ve masaüstünü özel olarak alır invoke, , dragclick, , hover, scroll --wheel, touch, pen, focus, send-keys,screenshot

Ortadaki satır anlamaya değer bir satırdır. set-value --to scroll --direction /ve scroll-into-view ön plan yerine UIA desenlerini kullanır, böylece başsız/kilitli oturum dostu kalırlar ve hiçbir zaman kimsenin masaüstünü kullanmasını engellemez. Ancak uygulamanın gösterdiklerini değiştirerek bir alanı düzenlemek veya başka birinin tıklamasıyla listeyi kaydırmak yerine başka bir iş akışının sırasını beklemelerini sağlar.

Bir iş akışında diğer paylaşılan çalışmayla çakışıyor; bu, bir record kişinin kaydettiği çağrıları set-value nasıl yakaladığıdır. Kendi iş akışlarının ileriye dönük engelini yok saymıyorlar : aynı iş akışının önceki DesktopExclusive bir komutu (a click, a screenshot) yine de her sonraki komutu engellediği gibi onları engeller, bu nedenle bir tıklama ve onu izleyen mutasyon bunları yazdığınız sırada kalır.

screenshot her zaman özel bir dönüş için kuyruğa alır. Her yakalama masaüstünü rahatsız etmez ( Windows Grafik Yakalama ile yakalanan sıradan görünür bir pencere) ama altyapı, simge durumuna küçültülmüşse hedefi geri yükler ve çerçeve yakalama kullanılamadığında veya --capture-screen canlı ekranı okuduğunda arka plana geri döner. Yakalama işlemi tamamlandıktan sonra yalnızca yüzeye ihtiyaç duyarlar, bu nedenle komut tahmin etmek yerine öne doğru döner. Birkaç pencereyi birleştirdiğinde hepsini tek bir özel dönüş altında yakalar, böylece kaydedilen görüntü, önceki ve sonrakinin karışımı yerine tek bir tutarlı an olur. Dosya kodlama ve yazma işlemi masaüstü yayımlandıktan sonra gerçekleşir.

--capture-screen tam olarak bir pencereye ihtiyaç duyar. Canlı ekran yakalama, gerçekte önünde olan her şeyi kaydeder ve yalnızca bir pencere olabilir. Ile açıkça bir pencere seçildiğinde tam olarak -w <hwnd> tek bir bölge (bu pencerenin sınırları içindeki pikseller, herhangi bir iletişim kutusu veya üzerine görünür bir şekilde yer paylaşımı dahil) verir. Bu, ekranı ilk başta okumanın nedenidir. Birkaç üst düzey veya sahip olunan pencereyle eşleştiğinde -a böyle bir seçim yoktur, bu nedenle ön planla savaşmak yerine herhangi bir şeyi yakalamadan önce komutu başarısız invalid_arguments olur. ile komutunu çalıştırın winapp ui list-windows -a <app> ve yeniden deneyin veya kendi içindeki her pencereyi birleştirmeye bırakın--capture-screen.-w <hwnd>

record kendi sırasını paylaşır, böylece aynı iş akışı girişi yakalamayla kesişebilir; bu şekilde bir uygulamayı yönlendiren bir iş akışını kaydedersiniz. İki uyarı:

  • İş akışı kimliği olmayan A record tek seferlik bir sahip olduğundan, süresi boyunca diğer tüm iş akışlarını engeller. Aynı anda kaydetmek ve tıklamak için her iki komutu da aynı WINAPP_UI_WORKFLOW_IDşekilde verin.
  • Çerçeve yakalama desteği olmayan bir konakta kayıt, boş çerçeve kurtarması her an pencereyi ön plana alabilen PrintWindow'a geri döner. Burada masaüstü kaydın tamamı için tutulur ve komut çıktısında bunu söyler; aynı iş akışı girişi bile bekler.

Görebileceğiniz hatalar: invalid_ui_workflow_id (değişken ayarlanmış ancak boş veya 256 karakterden uzun), desktop_coordination_unavailable (koordinasyon durumu okunamaz ve güvenli bir şekilde yeniden oluşturulamaz veya daha winappyeni bir komut tarafından yazılmıştır), queue_capacity_exceeded ( diğer iş akışlarından 64 komut zaten bekliyor— sınır, başlattığınız işlemleri değil, canlı yabancı garsonları sayar, bu nedenle çıkan veya sonlandırılan komutlara ait girdiler yuva kaplamaz, ve kendi iş akışınızın komutları bu sınıra karşı değil birbirinin arkasında sıralar), ui_turn_busy (yield kendi iş akışınızda hala çalışan bir komut varken) ve cancelled (beklerken Ctrl+C, koddan 130çıkın).

Dönüş erken yayınlıyor: winapp ui yield

Dört saniyelik zarafet bir geri dönüşdür: bitirdiğinizden emin olamadığınızda masaüstünün ayrılmış kalmasını sağlar. Bunu söyleyebiliyorsanız, söyleyin; yield kimsenin ihtiyaç duyduğu bir zarafet için herkesi bekletmek yerine masaüstünü hemen teslim edin.

$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
  • Tek seferlik komutlar bir iş akışı kimliği ayarlamamalıdır. Bir komut olmadan, her komut tamamlandığında masaüstünü zaten serbest bırakır ve verim için hiçbir şey yoktur.
  • Çok adımlı iş akışları, özellikle de diğer iş akışları bekliyor olabilirken, bittiğinde sonuç vermelidir. Tek bir hızlı komuta mal olur ve diğer herkesten dört saniyelik bir durak kaldırır.
  • Bu bir kez etkili. İki kez veya yetkisiz kullanım zaten sona erdikten sonra başarılı olur ve raporlar { "released": false } ; bu bir betiğin normal sonudur, hata değil.
  • Başka bir iş akışının sırasını hiçbir zaman serbest bırakmaz. Masaüstünü başka biri tutuyorsa veya kimse tutmuyorsa, bu bir no-op.
  • Kendi iş akışınızda hala çalışan veya kuyruğa alınmış bir komut varsa (örneğin, bir kayıt) başarısız ui_turn_busyolur. Bunun altında serbest bırakmak, masaüstünü komutun ortasından uzaklaştırır, bu nedenle hiçbir şey serbest bırakılmaz ve çalışan komut etkilenmez. Bekleyin veya durdurun, sonra yeniden verim.
  • gerektirir WINAPP_UI_WORKFLOW_ID. Olmadan ile invalid_argumentsbaşarısız olur.
  • Hiçbir uygulama ve seçici almaz: pencere değil rezervasyon verir, bu nedenle uygulama kapandıktan sonra da çalışır.

Bekleyen bir komut, masaüstünü yoklama yerine serbest bırakan kişi tarafından uyandırılır, bu nedenle kuyruk beklerken neredeyse hiçbir maliyete mal olmaz ve iletim anında gerçekleşir. Her garson da zaman zaman kendi başına yeniden kontrol eder; bu da bir işlem sonlandırıldığında masaüstünü kurtaran ve hiçbir şey yayımlamayan şeydir: kuyruğun başındaki komut yarım saniyede bir görünür ve arkasındaki komutlar ( yine de baş çalıştırmadan önce çalıştırılamaz) birkaç saniyede bir.

Uygulamaları Hedefleme

İşlem adına göre

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

Pencere başlığına göre

winapp ui inspect -a "LICENSE - Notepad"
winapp ui inspect -a "Fix WinApp"     # partial title match

PID tarafından

winapp ui inspect -a 12345

HWND tarafından (kararlı — sekme/başlık değişikliklerinin devamı)

# 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

Bulma için, -a kararlı hedefleme için kullanın-w. Birden çok pencereyle eşleştiğinde -a , komut bunları seçmeniz için HWND'lerle listeler.

Seçiciler

İnceleme/arama çıkışında [brackets] gösterilen seçiciyi kullanarak öğeleri hedefleyebilirsiniz. Üç tür seçici vardır:

Selector Anlamı Example
MinimizeButton AutomationId (benzersiz olduğunda gösterilir — kararlı, tercih edilen) winapp ui invoke MinimizeButton -a myapp
btn-close-d1a0 Anlamsal bilgi (benzersiz AutomationId olmadığında gösterilir) winapp ui invoke btn-close-d1a0 -a myapp
Submit Name/AutomationId 'ye karşı düz metin araması (büyük/küçük harfe duyarlı olmayan alt dize) winapp ui invoke Submit -a myapp

AutomationId seçicileri geliştirici kümesi tanımlayıcılarıdır (AutomationProperties.AutomationId XAML'de). AutomationId kullanıcı arabirimi ağacının inspect tamamında benzersiz olduğunda ve search bunu doğrudan seçici olarak gösterdiğinde, bunlar düzen değişiklikleri, yerelleştirme ve ağaç yeniden yapılandırmasından sonra kalır.

Benzersiz AutomationId olmadığında slug seçicileri (örn. btn-close-d1a0) oluşturulur. Biçim: prefix-name-hash. Karma öğe kimliğini doğrular, ancak kullanıcı arabirimi değiştikten sonra eskiyebilir.

Çıkış biçimini inceleme

Komut, inspect renkli çıkışlı öğe ağacını gösterir (mavi seçici, yeşil ad, gri meta veriler):

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

Her satırdaki ilk sözcük seçicidir; bunu diğer ui komutlarla kullanın. Bir öğe benzersiz bir AutomationId'ye sahip olduğunda, doğrudan kullanılır (örneğin, TabView, NewTabButton). Benzersiz AutomationId olmadığında, oluşturulan bir bilgi kullanılır (örn. tab-newtab-5f5b).

Anlamsal sümüklü böcekler

Bilgi kümeleri şu biçimi kullanır: prefix-normalizedname-hash burada:

  • ön ek — 3 harfli tür kısaltması (btn, txt, chk, cmb, itm, tab, img, lbl, pn, win, grp, lnk, mnu vb.)
  • normalizedname — AutomationId (tercih edilen) veya Ad,en fazla 15 karakterden küçük alfasayısal
  • hash — öğenin RuntimeId değerinin 4 karakterli onaltılık karması (öğe kimliğini doğrular)

Bilgi kümeleri kabuk açısından güvenlidir (özel karakter yoktur), benzersizdir ve doğrudan bağımsız değişken olarak kullanılabilir. Sorgu filtreleri olmadan karma eskime algılaması sağlar; öğe değiştirildiyse şunu alırsınız: "Öğe değişmiş olabilir. İncelemeyi yeniden çalıştırın." Filtrelenmiş sorgular için bkz . Kapsamlı ve yazılan sorgular.

Name veya AutomationId içermeyen öğeler yalnızca ön ek + karma (örn. pn-c8a3) gösterir.

Birden çok eşleşmeyi kesinleştirme

Çıkıştan alınan inspect/search bilgi kümeleri benzersizdir, ancak düzen değişiklikleri arasında değişiklik yapabilir; bunları birden çok eşleşme olduğunda düz tür adları veya metinler üzerinde kullanın. Seçici belirsiz olduğunda, CLI tüm eşleşmeleri kendi sümüklüböcekleriyle yazdırır, böylece doğru olanı seçip bu bilgiyle yeniden çalıştırabilirsiniz.

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

Öğeleri aramak için düz metin kullanın; özel söz dizimi gerekmez:

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

Bir metin araması birden çok öğeyle eşleştiğinde (ör. Grup, Düğme ve Metin'in aynı adı paylaştığı SettingsExpander), CLI otomatik olarak tek çağrılabilen öğeyi seçer. Birden çok çağrılabilirse, tüm eşleşmeleri sümüklü böceklerle listeler.

Çağrılamaz arama sonuçları için (örneğin, bir Düğmenin içindeki TextBlock), arama otomatik olarak en yakın çağrılabilen üst öğeyi ( ile invokekullanabileceğiniz üst öğe) ortaya çıkar. Bu, tüm arama seçicileri için çalışır:

  lbl-savechanges-a1b2 "Save changes" (120,40 80x20)
        ^ invoke via: btn-save-c3d4 "Save"

Yüzey seçici doğrudan kullanılabilir:

winapp ui invoke btn-save-c3d4 -a myapp    # invoke the parent Button

Commands

statü

Bir uygulamaya bağlanın ve bağlantı bilgilerini gösterin.

winapp ui status -a notepad
winapp ui status -a notepad --json

Incelemek

Kullanıcı arabirimi öğesi ağacını görüntüleyin. Çıktı, hiyerarşi için 2 boşluk girintili anlamsal bilgi kümelerini gösterir:

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

Örnek çıkış (varsayılan):

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)

Örnek çıkış (--interactive — yalnızca çağrılabilen öğeler, düz liste):

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)

Öğeler şu durum işaretleyicilerini gösterebilir:

  • [on] / [off] / [indeterminate] — geçiş/onay kutusu durumu
  • [collapsed] / [expanded] — ağaçlar, birleşik giriş kutuları, menü öğeleri için genişletme/daraltma durumu
  • [scroll:v] / [scroll:h] / [scroll:vh] — kaydırılabilir kapsayıcı (dikey, yatay veya her ikisi)
  • [offscreen] — öğe ekranda görünmüyor
  • [disabled] — öğesi etkinleştirilmedi
  • value="..." — düzenlenebilir öğeler için geçerli metin içeriği (Ad'dan farklı olduğunda)

Seçiciyle eşleşen öğeleri bulun. Çıkışta semantik bilgi kümeleri gösterilir:

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

Örnek çıkış:

  btn-minimize-d1a0 "Minimize" (1222,206 48x48)
  btn-maximize-e2b1 "Maximize" (1270,206 48x48)
  btn-close-d1a2 "Close" (1318,206 48x48)

Çıkışta gösterilen bilgi kümeleri (örneğin, btn-minimize-d1a0) doğrudan diğer komutlarla kullanılabilir:

winapp ui invoke btn-minimize-d1a0 -a notepad

get-property

Öğeden özellik değerlerini okuma. Desene özgü durumu (ToggleState, Value, IsSelected vb.) içerir.

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

Özellik adları büyük/küçük harfe duyarlıdır. Aşağıdaki altı metin biçimlendirme özniteliğinin tümü de dahil olmak üzere özellikleri listelemek için altında bilinmeyen bir ad ile invalid_arguments--json--property başarısız oluyor; atla. wait-for --property aynı büyük/küçük harfe duyarlı adları kullanır ve yoklamadan önce bilinmeyen adları reddeder.

Tam belge metin biçimlendirmesi

Biçimlendirme, geçerli seçimi veya şapka işaretini değil, öğenin TextPattern belgesinin tamamında okunur. Okumalar odağı veya seçimi değiştirmez.

Property Tekdüzen değer (dize olarak döndürülür)
FontWeight (Normal) veya "700" (kalın) gibi "400" sayısal ağırlık
FontName Yazı tipi aile adı, örneğin "Courier New"
FontSize Nokta cinsinden boyut, örneğin "15.5"
ForegroundColor RGB(12, 34, 56) gibi "3678732" ondalık Windows COLORREF (0x00BBGGRR)
IsItalic "True" veya "False"
StrikethroughStyle (Yok) veya "1" (tek) gibi "0" sayısal UIA metin düzenleme stili

Sayılar sabit biçimlendirme kullanır (yerel ayarınızdan bağımsız olarak ondalık ayırıcı). Her öznitelik bunun yerine şunu döndürebilir:

Değer Anlam ve sonraki adım
"Mixed" Biçimlendirme belge içinde değişir. Bunu tekdüzen bir değer olarak ele alma; bu komut tek tek metin aralıklarını sorgulamaz.
"NotSupported" Belgenin TextPattern sağlayıcısı bu özniteliği bildirmiyor. Uygulamanın erişilebilirlik desteğini denetleyin.
"Unavailable" öğesinde TextPattern yok. Metin/belge öğesini bulmak için veya search kullanıninspect.

Tüm özellikleri listelerken, canlı öğe çözümlenemiyorsa önbelleğe alınmış temel özellikler kullanılabilir durumda kalır ve diğer özellikler atlanmadan yanlış biçimlendirilmiş biçimlendirme değeri atlanır. Bu eksiklikler uyarı olarak günlüğe kaydedilir. Eksiklik yerine hata almak için belirli bir biçimlendirme özelliği isteyin.

Sağlayıcı hataları hata olarak kalır, hata olarak kalır "Unavailable". için stale_elementuygulamayı yeniden inceleyin ve geçerli seçiciyle yeniden deneyin.

JSON zarfı , elementIdtürü ve elementdize değerli propertiesiçerir. dahil olmak üzere BoundingRectanglemevcut özellikler biçimlerini saklar. Örneğin, öğesinin biçimlendirme bölümü properties şöyledir:

{
  "FontWeight": "700"
}

ekran görüntüsü

Bir pencereyi veya öğeyi PNG olarak yakalayın.

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)

Öğe seçicisi olmadan varsayılan yakalama, birden çok pencereyi ayrı dosyalar değil , yan yana bileşik PNG etiketli tek bir dosyada birleştirir. -a işlem adına göre veya PID, uygulamanın pencerelerini ve sahip oldukları pencereleri içerir. Başlık tabanlı -a eşleşme, eşleşen bir pencereyi ve sahip olduğu pencereleri seçer; -w işlemdeki her pencereyi değil, bir pencereyi ve sahip olduğu pencereleri açıkça seçer. Bu nedenle, ana HWND'yi açıkça seçtiğinizde bile sahip olunan bir iletişim kutusu veya araç ipucu kendi paneli olarak görünebilir. Bir öğe seçici, pencere oluşturmak yerine bu öğeye kırpılır.

--quiet kaydedilen yol da dahil olmak üzere hem tek pencereli hem de bileşik yakalamalar için bilgi çıkışını gizler. Uyarılar ve yakalama hatası tanılamaları görünür durumda kalır. Bunun yerine dosya yoluna ve boyutlarına yapılandırılmış çıkış olarak ihtiyacınız olduğunda kullanın --json .

ile --on sandboxkonak --output hedefini adlandırın. Başarılı düz çıkış ve --json görüntü teslim edildikten sonra ana bilgisayar yolunu bildirir.

Varsayılan yakalama yolu Windows kullanır. Graphics.Capture (WGC), DWM bileşik yüzeyini okuyarak yuvarlatılmış köşeleri, saydamlığı ve pencere diğer windows tarafından gizlenirken bile çalışmayı korur. WGC kullanılamıyorsa (eski Windows derlemeler) CLI, PrintWindow'a geri döner.

Hedef pencereye ait olmayan yer paylaşımları da dahil olmak üzere ekran konumlarında görünür açılır pencerelere veya araç ipuçlarına ihtiyacınız olduğunda kullanın --capture-screen -w <hwnd> . Etiketli paneller oluşturmak yerine bu pencerenin ekran bölgesini okur ve önce pencereyi ön plana getirir. ile -atam olarak bir eşleşen pencere gerektirir; birden fazla üst düzey veya sahip olunan pencere eşleşiyorsa ile kullanın winapp ui list-windows -a <app> ve yeniden deneyin -w <hwnd>. Yalnızca yakalama modlarını değiştirmeden pencereyi ön plana almak istiyorsanız kullanın --focus (örneğin, ekran görüntüsünün kullanıcının şu anda baktığıyla eşleştiğinden emin olmak için).

Ekran DC'sinin önünde ne varsa yakaladığından, --capture-screenyakalamadan hemen önce hedefin ön plana ulaştığını doğrular ve yakalamadıysa başarısız olur foreground_not_target (odak çalma önleme, UAC istemi veya kendini etkinleştiren başka bir pencere). Bu durumda hiçbir resim yazılmıştır; daha önce komut 0'dan çıktı ve yanlış pencerenin resmini geri verdi. ui record --capture-screen aynı denetimi ilk kareden önce uygular.

kayıt

Bir pencereyi veya öğe bölgesini H.264 MP4'e kaydedin. Katılımsız betikler için pozitif --duration-sec bir tercih. Süre olmadan, kayıt Ctrl+C veya yeniden yönlendirilen stdin için yeni satır veya EOF'ye kadar devam eder. npm uiRecord ve targetRecord yardımcıları 1 ile 86400 arasında bir tamsayı durationSec gerektirir; iptal sinyalleri kaydı düzgün bir şekilde sonlandırmak yerine zorla iptal eder.

# 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

Seçenekler:

  • --duration-sec N — N saniyelik kayıt. Durdurulana kadar varsayılan 0 kayıt.
  • --fps N — Saniye başına hedef kare sayısı (varsayılan 15).
  • --max-edge N — En uzun kenarın en fazla N piksel olması için ölçeği küçültün (0 = alt ölçek yok).
  • --capture-screen — Ekran DC'sinden yakalama (yer paylaşımları/açılır pencereler içerir; pencereyi ön planlar).
  • --output <path> — Çıkış MP4 yolu. Varsayılan değer recording-<timestamp>-<guid>.mp4’dır.
  • --overwrite — Yeni kayıt tamamlandıktan sonra var olan kayıt çıkışlarını değiştirin. Bu olmadan, mevcut çıkışlar reddedilir.
  • --frames — zaman damgalı JPEG kanıtlarını öğesine <output-name>.framesyazın. 1-30 fps ve --max-edge 64-4096 (varsayılan 1280) destekler. Çerçeve verileri 1 GiB ile eşlenir; üst sınıra ulaşılırsa MP4 devam eder.

Aracı tarafından okunabilir çerçeve yapıtları:

evidence.mp4
evidence.frames/
  manifest.json
  frames.ndjson
  frames/
    frame-000000-t000000000012.jpg

frames.ndjson, monoton , MP4 göreli mediaTimeMs, , imageIndexfileve changedile sampleIndexörnek başına bir satıra sahiptir.elapsedMs Birbirini izleyen piksel özdeş örnekler önceki quality-85 JPEG dosyasını yeniden kullanabilir.

manifest.json isteği, zamanlamayı, MP4 durumunu, görüntü boyutlarını ve durumunu (complete, partialveya truncated) kaydeder. Kesilmiş zamanlama korumalı ön eki kapsarken video , tam MP4'ü açıklar.

Kaydı ile --overwritedeğiştirmek istemiyorsanız yeni bir çıkış yolu seçin. Bu olmadan, atladığınızda --framesbile mevcut bir video veya eşleştirilmiş .frames dizini kaydı engeller. Yeni yakalama başarısız olursa önceki MP4 olduğu gibi kalır. Başarıyla değiştirildiğinde, yeni kayıt --framesatlasa bile önceki çerçeve dizini olarak <output-name>.frames.previous-<id>korunur. Kısmi kanıtı koruyun ve yeniden denemeden önce bildirilenleri recoveryHint izleyin. MP4 sonlandırması başarısız olursa, korunan çerçeveler altında <output-name>.frames.partial-*yayımlanabilir. Çerçeve yapıtları şifrelenmemiş ekran içeriği içerir; bunları ekran görüntüleri veya video gibi işleyin.

ile --on sandboxhem MP4 hem de çerçeve dizini, atlandığında --output varsayılan çıkışlar da dahil olmak üzere konağa teslim edilir. Kesintiye uğramış kayıtlar ve tam masaüstü yakalama için bkz. Korumalı alan yakalama.

Yakalama modları (JSON mode alanında raporlanan):

  • wgc— Grafik Yakalama Windows (varsayılan; pencere doluyken çalışır).
  • printwindow — GDI PrintWindow (bu sistem/oturumda WGC kullanılamadığında geri dönüş; bunun yerine dc ekranını kullanmak için ile --capture-screen yeniden çalıştırın).
  • screen — Aracılığıyla EKRAN DC --capture-screen (yer paylaşımları/açılır pencereler içerir; pencereyi ön plana getirir).

JSON çıkışı (--json):

  • stdout: Tempo, durdurma nedeni, isteğe bağlı frameArtifactsve uyarılar da dahil olmak üzere son kayıt sonucu.
  • stderr: Satır başına bir JSON nesnesi: ilk kareden sonraki bir recording-started olay ve daha sonra kayıt başarısız olursa bir hata. Çerçeve yolları yalnızca çerçeve çıkışı etkin olduğunda eklenir.

Hata kodları:

  • element_not_found — Seçici eşleşmedi.
  • ambiguous_selector — Seçici birden çok öğeyle eşleşmiş; önerilen bir sümüklüböcek kullanın.
  • invalid_arguments — Seçenek değeri geçersiz.
  • output_exists — Kayıt çıkışı zaten var ve istenen seçenekler altında değiştirilemez.
  • frame_output_failed — Çerçeve çıkışı başarısız olduktan sonra hiçbir yapıt korunamadı.
  • partial_output— Yalnızca bir yapıt tamamlandı; ve 'i recoveryHintinceleyinpartialOutput.

Bilinen sınırlama: Pencereli bir açılan pencere içindeki bir öğeyi kaydetmek, temel alınan pencereyi yakalayabilir. Tüm pencereyi kaydedin veya hareketsiz bir görüntü için ekran görüntüsü katman iş akışını izleyin. Bkz. #646.

Çağırmak

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

Testin tam olarak seçili öğe üzerinde belirli bir işlem gerçekleştirmesi gerektiğinde kullanın --action . İstenen eylem başarısız olsa bile hiçbir zaman başka bir deseni veya çağrılabilen bir atayı denemez. ile --action selecthem çağırmayı hem de seçimi destekleyen bir denetim seçilir, çağrılmayacak. ile --action, bir slug tam olarak bir öğeyi hedefler; birden fazla öğeyle eşleşen bir düz metin veya AutomationId seçicisi, ilk eşleşmede işlem yerine sıfır olmayan bir çıkış koduyla kapatılamaz, bu nedenle ad belirsiz olduğunda öğesinden inspect/search bir bilgi geçirebilirsiniz.

Action Operation
invoke InvokePattern.Invoke
select SelectionItemPattern.Select
toggle TogglePattern.Toggle, tam olarak bir kez
toggle-on / toggle-off ToggleState okuma; zaten doğru olan bir durumu değiştirmeden başarılı olun, aksi takdirde geçiş yapıp
expand / collapse ExpandCollapsePattern.Expand / Daralt

ve toggle-offiçintoggle-on, başlangıç Indeterminate durumu en fazla iki geçişe izin verir ve her birinin durumunu denetler. Diğer başlangıç durumları bir geçişe izin verir. İstenen duruma ulaşılmazsa, geçiş yapmaya devam etmek yerine komut başarısız olur. Başarısız bir doğrulama denetimin değiştirilmesine neden olabilir; daha sonra ne yapacağına karar vermeden önce okuyun ToggleState .

olmadan --action, mevcut otomatik davranış değişmez: InvokePattern, TogglePattern, SelectionItemPattern'ı ve ardından gerektiğinde bir invokable-ancestor yeniden deneyerek ExpandCollapsePattern'ı (genişletme) deneyin.

Desteklenmeyen bir eylem sıfır olmayan bir çıkış koduyla ve ile stderr'da yapılandırılmış bir hatayla --jsonbaşarısız olur. Seçili denetimi inceleyin ve desteklediği bir eylem seçin veya hedeflenen üst öğeyi açıkça hedefleyin. Başarı JSON'ı içerir requestedAction ve performedAction; bkz. JSON başvurusu.

click

Fare benzetimini kullanarak ekran koordinatlarında bir öğeye tıklayın. Desteklemeyen InvokePattern denetimler için bunu kullanın (örneğin, sütun üst bilgileri, liste öğeleri).

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

Diğer giriş ekleme fiilleri gibi, click hedefi ön plana getirir ve yanlış pencereye tıklamak yerine hızlı başarısız olur (no_interactive_desktop kilitli/güvenli bir masaüstünde, foreground_not_target odak aktarılamıyorsa). Ayrıca , düğme aşağı doğru konumlandırıldıktan hemen önce öğeyi yeniden çözümler: İmleci konumlandırdıktan sonra son bir konum denetimi yapar, bu nedenle tıklama boş alana geldikten sonra başarıyı raporlamak yerine sürekli hareket eden/animasyon oluşturan bir hedef başarısız olur target_moved ; bildirilen bir başarı, düğme kapatıldığında hedefin hala yerinde olduğu anlamına gelir.

sürüklenme

Bir noktada fare düğmesine basın, başka bir noktaya gidin, ardından ile drag <from> <to>serbest bırakın; burada her uç nokta bir öğe seçicidir (öğenin merkezinden/merkezine sürüklenerek) veya tam olarak tarafından x,ybildirilen winapp ui inspect. Serbestçe karıştırın ve eşleştirin (seçici→selector, seçici→coords, coords→coords).

Uygulamanın gerçekçi bir ileti akışı SendInput görmesi için ara taşımaları kullanırWM_MOUSEMOVE. Tutamaçları, kaydırıcıları, tuval çizimlerini ve sürükleyip bırakma işlemlerini yeniden sıralamak/yeniden boyutlandırmak için kullanın.

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

Seçenekler:

  • --right — Sol düğme yerine sağ fare düğmesiyle sürükleyin.
  • --hold-ms <ms> — Taşımadan önce düğmeyi başlangıçta basılı tutun (varsayılan: 0). ( <from> == <to> Hareket olmadan) bu işlem bir basma ve basılı tutma / uzun basma hareketi gerçekleştirir.
  • --dwell-ms <ms> — Hareket ettikten sonra, serbest bırakmadan önce hedefe (varsayılan: 0) dikkat edin. Düğmeyi açmadan önce, sürekli bir vurgulamadan (imlecin anında gelmesi yerine) kolundaki yer paylaşımlarını bırakmanızı / birleştirmenizi sağlar.

x,y Çıplak, aynı alan winapp ui inspect/search raporundaki ekran koordinatlarıdır ve bir seçici öğenin merkezine çözümlenir; önce noktaları seçmek için inceleyin.

gibi send-keys --via send-input, drag hedefi ön plana getirdikten sonra ekran koordinatlarına işletim sistemi genelinde ekler. Odak hedefe getirilemiyorsa (örneğin, arka plan işleminden odak çalma önleme), komut yanlış pencereye sürüklemek yerine () başarısız olur (foreground_not_target önce odak veya pencereye tıklayın). Kilitli/güvenli bir masaüstünde ile no_interactive_desktopbaşarısız olur. Her öğe uç noktası sürüklemeden hemen önce yeniden çözümlenir; hala hareket ediyorsa/yeniden boyutlandırıyorsa (bir animasyon hedefi), komutu eski bir noktaya sürüklemek yerine ile target_moved başarısız olur. (Çıplak x,y uç noktalar yeniden doğrulanamaz, bu nedenle as-iskullanılır.)

dokunmak

Windows işaretçi ekleme API'sini kullanarak yapay dokunma hareketleri ekleyin. Kişi bağlantısı bir öğe seçicidir (öğenin merkezini kullanır) veya (aynı boşluk x,y raporları) aracılığıyla açık winapp ui inspect. Fare benzetiminin ifade edebildiği dokunma/basma etkileşimleri ve çoklu dokunma hareketleri için kullanın.

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)

Seçenekler:

  • --gesture <g> — tap (varsayılan), double-tap, long-press, swipe, pinch, stretch.
  • --at <x,y> — Açık başlangıç noktası (ekran koordinatları). Varsayılan olarak seçicinin öğe merkezini kullanır.
  • --to-point <x,y> — Bir swipeiçin bitiş noktası. ' den önceliklidir --direction.
  • --direction <right|left|up|down> — Çekme yönü (varsayılan: right). verilmediğinde --distance bitiş noktasını hesaplamak için ile birleştirilir--to-point.
  • --distance <px> — Parmağınız için pinch/stretchyayılır veya piksel cinsinden uzaklığı çekin.
  • --hold-ms <ms> — Kaldırmadan önce kişileri basılı tutun (uzun basılı tutma süresi; ayarlanmadığında varsayılan olarak 500 ms'ye long-press ayarlanır).
  • --duration-ms <ms> — Hareket hareketleri için kayma süresi (çekme/sıkıştırma/uzatma; varsayılan 300).
  • --fingers <n> — Kişi sayısı (1-10; varsayılan 1). pinch / stretch her zaman 2 kullanın.

Enjeksiyon güvenliği. touch sıfır olmayan bir hedef pencere tutamacı çözümlenmediği ve bu pencerenin ön planı tutmadığı sürece ekleme yapmayı reddeder; hiçbir pencere çözümlenemediğinde, no_target odak aktarılamıyorsa veya foreground_not_target kilitli/güvenli bir masaüstünde başarısız olurno_interactive_desktop. Her koordinat (öğe merkezi, açık --at/--to-pointve oluşturulan yol noktaları) hedef pencere dikdörtgeni üzerinde denetlenmektedir; pencerenin dışındaki bir nokta önemli olmayan bir uyarı (içinde bir warnings[] girdi --jsonveya metin modunda bir uyarı satırı) olarak gösterilir ve ekleme işlemi devam eder ve yine de pencere dışı koordinatlara eklenen fare fiilleriyle (click/drag/hover/scroll) eşleşerek devam eder. --fingers yukarıdaki 10 ön reddedilir.

Donanım notu. Touch, modern yapay işaretçi cihazını (CreateSyntheticPointerDevice(PT_TOUCH)) tercih eder ve eski InitializeTouchInjection/InjectTouchInput API'ye geri döner. Ekleme geçerli cihazda/oturumda desteklenmiyorsa, komut hatalı bir başarı bildirmek yerine gerçek Win32 hata kodunu (örneğin "desteklenmeyen") ortaya çıkar; sıfır olmayan bir çıkışı "dokunma teslim edilmedi" olarak kabul eder.

Uzak Masaüstü / VM oturumları. bir Uzak Masaüstü (RDP) veya bazı VM oturumlarında işletim sistemi, hedef uygulamaya ulaşmadan yapay dokunmayı (0'dan çık) kabul edebilir. Uzak oturum algılandığında, touch bir teslim belirsizliği uyarısı (içindeki warnings[]bir --json girdi veya metin modunda bir uyarı satırı) ekler. ✅/exit 0, uygulamanın girişi aldığından değil ekleme çağrısının başarılı olduğu anlamına gelir; önemli olduğunda etkisini ui screenshot/ui inspect onaylayın.

kalem

yapay kalem/ekran kalemi girişi ekleme ( dokunmalar ve mürekkep vuruşları) Windows yapay işaretçi API'sini (CreateSyntheticPointerDevice(PT_PEN); Windows 10 1809+). Bir öğe merkezini, açık --at bir noktayı veya tam --path mürekkep vuruşunu hedefleme.

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

Seçenekler:

  • --at <x,y> — Kalem temas noktası (ekran koordinatları). Varsayılan olarak seçicinin öğe merkezini kullanır. Verildiğinde --path yoksayılır.
  • --path "<x,y x,y …>" — Boşlukla ayrılmış x,y çiftler olarak mürekkep vuruş yolu (tek noktalı yol bir dokunmadır).
  • --pressure <0.0–1.0> — Kalem basıncı (varsayılan 0,5).
  • --tilt-x <deg> / --tilt-y <deg> — Kalem eğim açıları, −90 - 90 (varsayılan 0).
  • --eraser — Ucu yerine kalemin silgi ucunu kullanın.
  • --duration-ms <ms> — Yol boyunca ilişkilendirilmiş UPDATE çerçeveleri olarak dağıtılan milisaniye cinsinden toplam vuruş seyahat süresi (varsayılan: yol noktası başına yaklaşık 10 ms). Kalemin baştan sona ne kadar hızlı hareket eteceğini denetlemek için bunu kullanın.

Enjeksiyon güvenliği. gibitouch, pensıfır olmayan, ön planlı bir hedef pencere (no_target / foreground_not_target / no_interactive_desktop) olmadan ekleme yapmayı reddeder ve her mürekkep noktasını hedef pencere dikdörtgenine karşı denetler ve pencere dışı koordinatları önemli olmayan bir uyarı (warnings[]--jsoniçinde veya metin modunda bir uyarı satırı) olarak yine de eklerken fare fiilleriyle tutarlı olarak denetler. Geçersiz --pressure (0,0–1,0 dışında) veya eğme (±90° dışında) ön tarafa reddedilir.

Uzak Masaüstü / VM oturumları. Kalem yönlendirmesi özellikle Uzak Masaüstü üzerinde güvenilir değildir: Ekleme çağrısı, hiçbir kalem girişi uygulamaya ulaşmazken başarıyı bildirebilir (çıkış 0). Uzak oturum algılandığında, pen bir teslim belirsizliği uyarısı (warnings[]--jsoniçinde veya metin modunda bir uyarı satırı) ekler, bu nedenle ✅ onaylanan teslim için yanlış değildir. Yerel, etkileşimli bir masaüstünde kaleme bağımlı akışları doğrulayın.

Hover

Fareyi öğenin merkezine getirerek vurgulama efektlerini (araç ipuçları, açılır öğeler, görsel durumlar) tetikler. Küçük bir wiggle ile gerçekçi fare hareketi için kullanılır SendInput , ardından yapılandırılabilir bir bekleme süresi bekler.

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

Seçenekler:

  • --dwell-time <ms> — Efektlerin görünmesi için üzerine gelindikten sonra beklenmesi gereken milisaniye cinsinden süre (varsayılan: 800, aralık: 0–10000)

gönderme anahtarları

Yapay klavye girişi gönderme — klavyeye karşılık gelen click. UIA'nın klavye ekleme deseni yoktur, bu nedenle win32 katmanına düşer. Klavye gezintisi (oklar, Sekme, Enter, Esc), kısayollar (ctrl+c, alt+f4) ve 's atomik yazma yerine set-valuetuş vuruşu başına olay gerektiren denetimlere yazmak için kullanın.

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

Anahtar dil bilgisi (boşlukla ayrılmış belirteçler, tırnak çok belirteçli dizeler):

  • Adlandırılmış anahtarlar — enter/return, tab, esc/escape, space, , backspace, delete/del, insert, homeend, pageup/pguppagedown/pgdn, up/down/left/right,f1f16, apps, . printscreencapslock
  • Sıralar — birden çok belirteçe sırayla basılır: down down enter.
  • Değiştirici birleşik girişler — ctrl, shift, alt, win ile +birleştirilir: ctrl+shift+t, alt+f4.
  • Değişmez metin — bilinen bir anahtar olmayan tüm belirteçler karaktere göre yazılır: hello. Bitişik değişmez sözcükler aralarındaki boşluğu korur, bu nedenle gibi "Hello world" tırnak içine alınmış bir tümcecik tamsayı (boşluk korunur); gibi yalnızca metin içeren +C++ veya a+b metin olarak yazılan, birleşik giriş olarak ayrıştırılmayan bir değişmez değerdir.
  • Açık değişmez değer kaçış — bir anahtar veya değiştirici adıyla çakştığında bile belirteci text= ile birlikte yazın: text=enter Enter tuşuna basmak yerine "enter" sözcüğünü yazın ve text=ctrl+a değişmez değer dizesini yazın. Kaçışı vk= yansıtır; kaçış değeri bitişik değişmez sözcüklerle (text=down low → "aşağı düşük") birleşmektedir. Belirteçler boşlukla bölündüğünden (ve bitişik değişmez değerler tek bir boşlukla yeniden birleştirildiğinden), bir değerin içinde text= ters eğik çizgi kaçışları kullanarak aksi halde hayatta kalamayacak boşluklar yazın: \s boşluk, → → sekmesi, \t\n yeni satır \r → → → \\ değişmez çizgi. \n, \rve \r\n her biri tek satır sonu (Enter / VK_RETURN) ekler ve text=line1\nline2 her text=line1\r\nline2 ikisi de tek bir yeni satır yazar. Bu nedenle text=a\s\sb "a b" (çift boşluk) yazar ve text=\shi başında bir alan tutar. Tanınmayan bir kaçış (örn. \x) açık bir şekilde bırakılır.
  • Tam bağımsız değişken değişmez değeri (--verbatim) — yükün tamamı değişmez metin olduğunda, ile --verbatimher belirteçten kaçmak yerine geçirintext=. Tam olarak verilen anahtar bağımsız değişkenini (adlandırılmış anahtar/birleşik giriş/vk=/text= yorumlama olmadan) yazar ve normal yoldan farklı olarak, ihtiyaç \sduymadan tam iç boşluğu (daraltma olmadan) korur. Bu nedenle send-keys "down down enter" --verbatim sözcükleri yazın ve send-keys "a b" --verbatim çift boşluğu korur. Ters eğik çizgi kaçışlarının kodu modda çözülemez--verbatim ( \s ters eğik çizgi ve "s" olarak yazılır); kaçış denetimi karakterine ihtiyacınız olduğunda belirteci kullanın text= .
  • Kolay ad içermeyen anahtarlar için ham sanal anahtarlar — vk=0xNN (onaltılık) veya vk=NN (ondalık).

Seçenekler:

  • --target <selector> — Anahtarları göndermeden önce bu öğeye (UIA aracılığıyla) odaklanın. Anahtarlar bu olmadan uygulamanın şu anda odaklanmış olan öğesine gider.
  • --verbatim — Anahtar bağımsız değişkeninin tamamını değişmez metin (anahtar/birleşik giriş/vk=/text= ayrıştırma yok) olarak yazın ve tam boşluğu koruyun. Belirteç text= başına çıkışın tam bağımsız değişken biçimi.
  • --via <transport>— post-message (varsayılan) gönderileriWM_KEYDOWN/WM_KEYUP/WM_CHARhedef pencerenin kuyruğuna gönderir. HWND tarafından hedeflenir ve UIPI'yi atlar (bütünlük düzeylerinde çalışır). send-input aracılığıyla SendInput işletim sistemi çapında ekler ve ön plan penceresine gider.

Taşıma /bilinen sınırlar seçme:

  • post-message varsayılan değerdir çünkü UIPI'yi atlar ve pencerenin ön plan olmasına bağımlı değildir. Sınırlar: Alt düzey kancalar aracılığıyla WH_KEYBOARD_LL kaydedilen genel kısayol tuşlarını tetikleyemez (bu dokunma girişi herhangi bir pencere kuyruğunun yukarı akışı) ve aracılığıyla GetAsyncKeyState ham anahtar durumunu okuyan uygulamalar tutulan değiştiricileri gözlemleyemez. Ön plan oluşturma sonrasında hedef iş parçacığının odaklanmış alt penceresine (aracılığıyla GetGUIThreadInfo) otomatik olarak çözümlenir ve bu nedenle denetimleri ayrı alt pencereler olan klasik Win32/WinForms uygulamaları denetimi el ile hedeflemeden anahtarları alır. WinUI 3 / UWP uygulamalarının alt HWND içermeyen penceresiz XAML denetimleri vardır, bu nedenle gönderilen WM_CHAR/WM_KEYDOWN bir gönderinin inecek bir şeyi yoktur ve bırakılır ; ileti sonrası bunları yönlendiremez (komut uyarır ve 0'dan çıkar); kullanın.--via send-input (WPF pencereler tek HWND'dir ve dahili olarak odaklanmış öğeye yönlendiren anahtarlardır, bu nedenle ileti sonrası orada çalışır.)
  • send-input tam gerçek giriş üretir (değiştiriciler GetAsyncKeyState, alt düzey kancaları tetikler) ancak ön plan olan pencereye gider ve yükseltilmiş bir işlemden düşük bütünlüklü (AppContainer/AppX) hedefine eklenirken UIPI tarafından engellenir. Hata bildirirse send-input , hedef büyük olasılıkla yükseltilmiştir veya bir AppX uygulamasıdır; kullanın post-messageveya CLI'yi eşleşen bir bütünlük düzeyinde çalıştırın. Güvenlik görevlisi olarak, send-input odak buraya getirilemediğinde yanlış pencereye yazmak yerine eklemeden hemen önce hedef pencerenin gerçekten ön planda olduğunu ve başarısız olduğunu (foreground_not_target) doğrular; önce odak veya pencereye tıklayın. Kilitli veya güvenli bir masaüstünde bunun yerine ile başarısız olur no_interactive_desktop (eklenmek için ön plan penceresi yoktur) — oturumun kilidini açın veya UIA desenli fiilini (set-value, invoke) kullanın.
  • Sistem tarafından ayrılmış birleşik girişler (win+l, win+r, ctrl+shift+esc, ctrl+alt+del, alt+tab, alt+f4, ctrl+esc, , yalnız win/printscreen, ...) işletim sistemi genelinde gönderildiğinde yalnızca hedef yerine işletim sistemi/kabuk üzerinde hareket eder. send-inputbunları varsayılan olarak reddeder (ile ilgili hatalar invalid_arguments ve hiçbir şey göndermez), çünkü bunları işletim sistemi düzeyinde eklemenin hedef pencerenin çok ötesinde etkileri vardır (örneğinwin+l, oturumu kilitler). Kabul etmek için geçiş --allow-system-keys yapın; bu, PowerToys' win+shift+v veya win+r (küresel alt düzey kanca işletim sistemi genelinde giriş akışını izlediğinden eklenen birleşik giriş akışı tetikler) gibi genel bir kısayol tuşu kullanmanıza olanak tanır. ile --allow-system-keysbile engellenmiş durumda kalan özel durumlar:win+l otomasyondan kurtarılamayan iş istasyonunu LockWorkStation() kilitler (CI ve uzak masaüstü oturumlarını keser) ve ctrl+alt+del bayrağından bağımsız olarak eklenen girişten Windows bir Güvenli Dikkat Sırası (SAS) olduğundan, hiçbir zaman etkili olamaz, bu nedenle yanıltıcı bir başarı bildirmek yerine hatalar (invalid_arguments, çıkış 1) olur. Diğer birleşik girişlere (alt+f4, ctrl+shift+esc, , win+r...) bayrakla izin verilir — arayan dikkat edin. Alternatif olarak, belirli bir pencereye sistem birleşik girişini teslim etmek için, penceresi kapsamlı ve etkilenmeyen öğesini kullanın --via post-message(gönderilenler win+l zararsızdır, ancak gönderilenler alt+f4 hedef pencereyi kapatmaya devam eder).

Tuş vuruşu başına olaylar (KeyDown / TextChanged):

  • Adlandırılmış anahtarlar ve değiştirici birleşik girişler (down, enter, ctrl+shift+t, vk=0xNN) KeyDown aktarımda da gerçek KeyUp (ve ) tetikler; bunlar ayrıkWM_KEYDOWN/WM_KEYUP(veya SendInput sanal anahtar olayları) olarak teslim ederler.
  • Değişmez değerle yazılan metin (hello) taşımaya göre farklılık gösterir:
    • --via send-inputher karakteri etkin klavye düzenindeki sanal tuşuna (artı Shift) eşler, böylece hedef doğru sanal tuşa sahip orijinalKeyDown bir anahtar ve ardından işletim sistemi tarafından oluşturulan WM_CHAR (yükseltmeTextChanged) (karakter başına bir tam tuş vuruşu) görür. Geçerli düzende ulaşılamayan karakterler (veya Ctrl/AltGr gerekir) bir Unicode paketine geri döner, böylece tam karakter hala düşer. Tuş send-input vuruşu başına aslına uygunluk gerektiğinde kullanın KeyDown (ör. işleyici anahtarı kapalı TextBoxolan bir WinUI 3 / WPF KeyDown sürüş). Normal (yükseltilmiş olmayan) bir WinUI 3 test konağı için, ön plan penceresini hedeflediğinden winapp ui focus önce penceresini ön plana getirin (send-input/ tıklayın).
    • --via post-messagekarakter başına tek WM_CHAR bir karakter (yazılan metin için gönderi WM_KEYDOWN/WM_KEYUP; bunlar adlandırılmış tuşlar/birleşik girişler için ayrılmıştır) ve karakter başına KeyDown. Otomatik olarak pencerenin odaklanmış alt denetimine yeniden hedeflediğinden, klasik Win32/WinForms WM_CHARtemelli düzenleme denetimleri metni (yükselterek TextChanged) alır. Uyarı: WinUI 3 / UWP / XAML uygulamaları (winapp'in birincil hedefi) gönderilenleriWM_CHAR/ yoksayan WM_KEYDOWN denetimlere sahiptir; bu nedenle komut başarılı olduğunu bildirse de sabit metin veya adlandırılmış anahtarlar (Enter, rakamlar, ...) bunlara ulaşamaz. Hedef XAML gibi göründüğünde ve hala 0'dan çıktığında (PostMessage fire-and-forget olduğunda ve teslimi onaylayamazsa) bir uyarı yayar. WinUI 3 / UWP / WPF uygulamaları kullanmak için kullanın; klasik Win32 denetimleri için veya yalnızca bütünlük düzeylerinde pencere kapsamına ihtiyacınız olduğunda rezerve edin--via send-inputpost-message.

JSON çıkışı (--json): sonuç hwnd anahtarların teslim edildiği etkin penceredir; bunun için --via post-message komut yeniden hedeflendiğinde çözümlenen odaklanmış alt denetimdir (en üst düzey -w/-a/-e pencere olması gerekmez), bu nedenle otomasyon girişin tam olarak nereye ulaştığını onaylayabilir. Bu etkin hedef penceresiz bir XAML konağı gibi göründüğünde, yukarıdaki teslim uyarı da giriş warnings[] olarak (konsolda gösterilen aynı danışmanlık) ortaya çıkar, bu nedenle ✅ çıkış 0 doğrulanmış teslim için yanlış değildir.

set-value

Program aracılığıyla düzenlenebilir bir öğede bir değer ayarlayın (tuş vuruşu yok, uygulama ön planı yok). Geri dönüş zinciri kullanır:

  1. ValuePattern — TextBox, ComboBox, PasswordBox ve çoğu düzenlenebilir denetim.
  2. RangeValuePattern — değer sayı olarak ayrıştırıldığında sayısal denetimler (Slider, ProgressBar).
  3. LegacyIAccessible (IAccessible::put_accValue) — ValuePattern içermeyen TextPattern yalnızca düzenleme denetimlerinin geri dönüşüdür (ör. zengin düzenleme / Document oluşturma kutuları). Bu, böyle bir denetimi okuyabileceği ancak get-value okuyamadığı okuma/yazma boşluğunu set-value kapatır.
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

Üç desenden hiçbiri değeri ayarlayamazsa, set-value son çare olarak işaret send-keys eden net bir hatayla başarısız olur.

Her zengin düzenleyici programlı kümeyi desteklemez. LegacyIAccessible geri dönüşü yalnızca erişilebilirliği uygulayan denetimler IAccessible::put_accValue üzerinde çalışır; yerel Win32 zengin düzenleme denetimleri ve Chromium/Electron/WebView2 oluşturma yüzeyleri genellikle bunu yapar. WinUI 3 RichEditBox ve WPF RichTextBox programlı değer ayarını desteklemez; tasarım gereği içeriklerini salt okunur olarak UI Otomasyonu (Metin deseni, ayarlanabilir Değer düzeni yok) kullanıma sunar, bu nedenle set-value bunlara yazamaz. Bunlar için (kilidi açılmış, ön planlı masaüstü gerekir) kullanın send-keys .

get-value

Bir öğeden geçerli değeri okuyun. Akıllı geri dönüş zinciri kullanır: TextPattern (RichEditBox, Document) → ValuePattern (TextBox, Slider) → SelectionPattern (ComboBox, RadioButton, TabView) → Name (etiketler).

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

Başarıyla okunan boş bir metin alanı, erişilebilirlik etiketini değil, döndürür "text": "". Yalnızca boşluk içeriği de JSON'da korunur. wait-for --value "" boş bir alanla eşleşir; ister yeni olsun, ister düzenlendikten sonra temizlendi. Bunun yerine erişilebilirlik etiketini okumak için kullanın get-property --property Name.

focus

winapp ui focus txt-textbox-a4b1 -a notepad

Seçili denetimin penceresini gerektiğinde etkinleştirir ve ardından denetimi odaklar. Seçici gereklidir; veya -a <app>-w <HWND> kullanarak hedefi seçin. Başarı, pencerenin ön plan olduğu ve seçili denetimin komut döndürülmeden önce onaylandığı HasKeyboardFocus anlamına gelir. komutu, denetimin odağı raporlaması için 500 ms'ye kadar izin verir; hedef kaybolursa veya odağı geri almaya çalışmak yerine ön planı kaybederse durur. Ana pencerenin önündeki sahip olunan bir iletişim kutusu yeterli değildir: hedefiniz buysa iletişim kutusunda bir denetim seçin.

Bu komut kilitli olmayan, etkileşimli bir masaüstüne ihtiyaç duyar ve Windows etkinleştirme kısıtlamalarını atlamaz. ile foreground_not_targetbaşarısız olursa, hedeflenen pencereyi el ile etkinleştirin ve yeniden denemeden önce engelleme iletişim kutusunu denetleyin. için focus_not_acquiredgeçerli kullanıcı arabirimini inceleyin ve odaklanabilir bir denetim seçin. için stale_elementhedefi veya searchile inspect yeniden bulun. Bulma ve yeniden deneme komutlarında aynı --on hedefi koruyun.

görünüme kaydırma

Öğeyi görünür alana kaydırın.

winapp ui scroll-into-view itm-targetitem-c3d4 -a myapp

bekleme

Öğenin görünmesini, kaybolmasını veya bir değerin hedefe ulaşmasını bekleyin.

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

Kaydırma

Kapsayıcı öğesini kaydırma. Kaydırılabilir kapsayıcıları search scroll bulun; (dikey) veya [scroll:v] (yatay) işaretçileri arayın [scroll:h] .

# Find which elements are scrollable and in which direction
winapp ui search scroll -a myapp
#   pn-scrollview-bfef Pane "scrollView" [scroll:v] (main content, vertical)
#   pn-scrollviewer-bfb1 Pane "scrollViewer" [scroll:h] (horizontal list)

# Scroll the main content down
winapp ui scroll pn-scrollview-bfef --direction down -a myapp

# Jump to top/bottom
winapp ui scroll pn-scrollview-bfef --to bottom -a myapp

# If you target an element that's not scrollable, scroll walks up to find the nearest scrollable parent
winapp ui scroll itm-someitem-a1b2 --direction down -a myapp

# Synthesize real mouse-wheel input over the element (1 = one notch up, -1 = one notch down).
# Use this to test handlers that respond to the wheel directly (zoom, custom scroll) rather than ScrollPattern.
winapp ui scroll img-map-a1b2 --wheel -1 -a myapp

Seçenekler:

  • --direction <up|down|left|right> — aracılığıyla ScrollPatternartımlı olarak kaydırın.
  • --to <top|bottom> — aracılığıyla ScrollPatternbaşlangıç/bitişe atlayın.
  • --wheel <notches> — Tekerlek çentiklerinde (kalıplar) aracılığıyla öğenin merkezi SendInputüzerinde fare tekerleği girişini sentezleyin: 1 = bir çentik yukarı/uzağa, -1 = bir çentik aşağı/doğru, 3 = üç çentik yukarı. (Her çentik, tüketen WHEEL_DELTA 120 birimin WindowsSendInput; CLI sizin için çentikleri 120'ye kadar ölçeklendirir.) atlarScrollPattern.

--direction, --tove --wheel birbirini dışlar— tam olarak bir tane geçirin. --wheel Ekran koordinatlarına işletim sistemi genelinde giriş ekli olduğundan, hedefi önce ön plana getirir ve yanlış pencereyi kaydırmak yerine odak aktarılamazsa (foreground_not_target) başarısız olur.

odaklan

winapp ui get-focused -a myapp
winapp ui get-focused -w <HWND> --json

Seçili uygulamada klavye odağı olan öğeyi, uygulama sahipliği yalnızca kendi üst penceresinden kullanılabilen denetimler de dahil olmak üzere gösterin. ile -wodak, aynı işlemdeki başka bir pencereye veya sahip olunan bir açılan pencereye değil, o pencereye ait olmalıdır. ile -a, seçili işlemdeki diğer pencereler dahil edilir. Hiçbir odaklanmış öğenin hedefe ait olduğu doğrulanamazsa JSON çıkışı hasFocus:false vardır. Odak veya pencere sahipliği sorgusu başarısız olursa, komut sıfır olmayandan çıkar; öğesini yeniden deneyin get-focusedve pencere kapalıysa ile yeniden list-windows bulun.

list-windows

Açılır pencereler ve iletişim kutuları da dahil olmak üzere bir uygulama için tüm görünür pencereleri listeleyin. Varsayılan olarak, sıfır boyutlu adsız pencereler (görünmez sistem pencereleri) hariç tutulur.

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

verim

Dört saniyelik boşta kalma zarafetini beklemek yerine bu iş akışının kullanıcı arabirimini erken bırakın. WINAPP_UI_WORKFLOW_IDgerektirir; uygulama almaz ve seçici almaz. Bkz. Dönüş erken serbest bırakıyoruz.

winapp ui yield
winapp ui yield --json          # {"released": true} — or false when nothing was held

Çerçeve Desteği

Çerçeve Incelemek search Çağırmak set-value ekran görüntüsü
WPF ✅ Tam ağaç ✅ Tüm özellikler ✅ Tüm desenler ✅ ¹ ✅
WinForms ✅ ✅ ✅ ✅ ✅
Win32 ✅ ✅ ✅ ✅ ✅
WinUI 3 ✅ ✅ ✅ ✅ ¹ ✅
Elektron ⚠️ Krom ağacı ⚠️ Sınırlı ⚠️ Değişkenlik gösterir ⚠️ Değişkenlik gösterir ✅
Flutter ⚠️ Temel ⚠️ Temel ❌ En Az ❌ ✅

¹ set-value , ValuePattern/RangeValuePattern'ı ve erişilebilirliği uygulanan textPattern-only düzenleme denetimlerini (LegacyIAccessible geri dönüşü) ortaya çıkan tüm denetimlerde IAccessible::put_accValue çalışır. WinUI 3 RichEditBox ve WPF RichTextBox özel durumlardır; yalnızca salt okunur Metin desenini (ayarlanabilir Değer deseni yoktur) kullanıma sunar, bu nedenle tasarım gereği program aracılığıyla ayarlanamazlar; bunları yazmak için (etkileşimli masaüstü gerekir) kullanın send-keys .

Kendi kodunuzdan altyapıyı kullanma

Her şey winapp ui kitaplık olarak kullanılabilir, böylece CLI'ya kabuk oluşturmadan bir testten veya araçtan aynı otomasyonu çalıştırabilirsiniz:

Paket Eklenenler
Microsoft.Windows.SDK.BuildTools.WinApp.UIAutomation Denetleme, seçiciler, UIA desen etkileşimi, giriş ekleme, ekran görüntüleri
Microsoft.Windows.SDK.BuildTools.WinApp.UIAutomation.Recording MP4'e video kaydı ve çerçeve paketleri
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);

Belirleyici eylemler için , aşırı yüklemesini UiInvokeActionkullanın:

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 , çağrılabilen bir eşleşme seçmek yerine belirsiz metni reddeder. Tam AutomationId eşleşmeleri name veya AutomationId alt dizelerinden önceliklidir; benzersiz bir ad, AutomationId'i paylaşılmış olan bir denetimi seçebilir. Uygulama kapsamlı bir hedef için bu denetim, uygulamanın/sahip olunan pencerelerin tümünü kapsar. Seçim kapsamını kısıtlamak için (veya açık pencere kitaplığı hedefi) kullanın -w <HWND> .

CLI eylem sonucuyla aynı anlamlara sahip ve PerformedAction döndürürPattern. İnceleme veya seçim tarafından döndürülen bir öğeyi çalışma zamanı bilgisine veya benzersiz AutomationId'sine olduğu gibi geçirin. Açık eylemler, ad ve denetim türüne göre yeniden bağlama yerine eksik veya belirsiz bir kimliği reddeder.

Kapsamlı okumalar için başka bir değerine, tür adına ve ClassName değişmez değer sağlayıcı sınıfına ayarlayınUiSelector.Root. ControlTypeUiSelector Bunlar CLI ile aynı sorgu koşullarını kullanır. Yalnızca bir kök düzeyi desteklenir: selector.Root.Root olmalıdır null. İç içe yerleştirilmiş kök, hedef pencereye bakmadan önce oluşturur ArgumentException . Kök seçicileri iç içe yerleştirme yerine benzersiz bir kök AutomationId veya bilgi kümesi kullanın. UiControlTypes.GetId(name) resmi tür adlarını ve belgelenmiş iki diğer adı çözümleyip 0 geçersiz bir ad döndürür. UiControlTypes.GetName(id) kurallı adı veya Unknown(id) tanınmayan bir kimlik için döndürür.

JSON'dan GetPropertiesAsyncGetTextAsync veya öğesine geri yüklenen bir UiElement geçirirken ve WindowHandledeğerini Selector koruyun. Bir bilgi kümesi seçicisi özgün öğeyi tanımlamaya devam etmelidir; artık yoksa, bu okumalar aynı AutomationId veya ada sahip başka bir öğe seçmek yerine oluşturur UiElementNotFoundException . Sonucu yenilemek için özgün sorguyu yeniden çalıştırın. Kapsamlı okumalar ayrıca hataları null veya daha önce yakalanan bir değer döndürmek yerine genel UIA özellik alıcılarından ve alınan UIA desenlerinden yayılır.

Kayıt, yalnızca kullanıcı arabirimini inceleyen ve yönlendiren projelerin SkiaSharp'a çekmemesi için ayrı bir pakettir. Otomasyon paketi hem hem net10.0-windows10.0.19041.0de net10.0-windows öğesini hedefler; ikincisi Windows Grafik Yakalama ekler; bu, tıkalı veya GPU bileşik windows yakalamanıza olanak tanırscreenshot. Tam API ve hedef çerçevenin dengeleri için her paketin NuGet'te README'sine bakın.

UiTarget.FromWindowHandle, zaten size bir pencere veren test çerçeveleri için giriş noktasıdır; örneğinMSTest.Windows.UIAutomation, WindowTest.MainWindow ile MainWindow.Current.NativeWindowHandleköprü oluşturduğunuz uia2 AutomationElement değeridir.

Sorun giderme

Error Nedeni Çözüm
"Çalışan uygulama bulunamadı" Uygulama çalışmıyor veya ad uyuşmazlığı İşlem adını denetleme veya PID kullanma
"Birden çok pencere eşleşmesi" Belirsiz -a değer Listelenen seçeneklerden kullanın -w <HWND>
"birden çok pencere var" İşlemin birden çok penceresi var Belirli birini hedeflemek için kullanın -w <HWND>
"Seçici N öğeleriyle eşleşmiş" Belirsiz eski seçici Çıkıştan inspect gelen bilgi kümelerini kullanın veya eski seçicilere ekleyin[0]. [1]
"Öğe değişmiş olabilir" Bilgi karması geçerli öğeyle eşleşmiyor Yeniden çalıştırın inspect veya search yeni sümüklü böcekler almak için
"herhangi bir çağırma düzenini desteklemiyor" Öğe çağrılamıyor Çağrılabilen bir alt öğeyi bulmak için öğesinde kullanın inspect
"UIA penceresi bulunamadı" UIA işlemi göremiyor HWND'yi bulmak için kullanın list-windows ve ardından -w
"Pencerenin boyutu sıfır" Pencere simge durumuna küçültüldü Uygulama otomatik olarak geri yüklenecek
Açılan/açılan liste ekran görüntüsünde yok Varsayılan yakalama pencere başınadır ve eklenmemiş katman içermez Ile bir pencere seçmek için ekran görüntüsü yer paylaşımı iş akışını izleyin -w <hwnd> --capture-screen
foreground_not_target --capture-screen Windows etkinleştirmeyi reddettiğinden, ekran görüntüsü gerçekte önünde olan pencereyi kaydederdi Hedef pencereye tıklayın veya odak çalma penceresini kapatın ve yeniden deneyin veya bırakın --capture-screen
element_not_found kayıt sırasında Seçici verildi ama eşleşen öğe yok Yeniden çalıştırın inspect veya search yeni bir seçici alın
Kayıt sırasında WGC kullanılamıyor WGC yakalama başlatma başarısız oldu; sessiz geri dönüş yok GPU'ya/sürücüye bakın; screen-DC yakalamaya onay vermek için kullanma --capture-screen

Ortak Desenler

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

Metin bulma ve üst öğesini çağırma

# 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

Yinelenen öğeleri kesinleştirme

winapp ui search '#Image' -a myapp; winapp ui invoke itm-image-a2b3 -a myapp

Açılır yer paylaşımlı ekran görüntüsü

winapp ui list-windows -a myapp # use the main window's HWND below
winapp ui set-value txt-searchbox-e5f6 "query" -a myapp; winapp ui screenshot -w <hwnd> --capture-screen
winapp ui invoke btn-settings-a1b2 -a myapp; winapp ui wait-for pn-settingspage-c3d4 -a myapp --timeout 3000; winapp ui screenshot -a myapp -o settings.png

Bulma, tıklama ve doğrulama

winapp ui inspect -a myapp --interactive; winapp ui invoke btn-submit-7a90 -a myapp; winapp ui screenshot -a myapp

Dosya iletişim kutusu etkileşimi

Dosya açma/kaydetme iletişim kutuları, UIA desteğine sahip standart Windows iletişim kutularıdır:

# 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>

Belirli bir iletişim kutusunun gerçek bilgi kümelerini bulmak için kullanın inspect -w <dialog-hwnd> --interactive .

Zincirleme için neden ; (değil &&)

Yerel bir CLI stderr'a && yazdığında veya ANSI kaçış dizileri kullandığında PowerShell işleci donabilir. Bunun yerine kullanın ; ; her komutu koşulsuz olarak çalıştırır ve bu kilitlenmeyi önler. Bu, aracı iş akışları için de daha iyidir: Genellikle çağrı sıfır olmayan bir çıkışa sahip olsa bile ekran görüntüsünün çalışmasını istersiniz.

CI Test Desenleri

Duman testleri ve kullanıcı arabirimi doğrulaması için CI işlem hatlarında (GitHub Actions, Azure DevOps) winapp ui komutlarını kullanın. wait-for --property ve --value onay işlevi görür; zaman aşımında 1 çıkış kodunu döndürür ve CI adımı otomatik olarak başarısız olur.

GitHub Actions'da başlatma ve test

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

ile assert öğesi durumu wait-for

wait-for --value ( TextPattern → ValuePattern → SelectionPattern → Name) ile aynı akıllı geri dönüş get-value kullanarak öğenin değeri beklenen dizeyle eşleşene kadar yoklar. Eşleşmede 0 çıkış kodu, zaman aşımında çıkış kodu 1'i döndürür; bu da ci kullanımı kolay bir onaydır. Bunun yerine belirli bir UIA özelliğini denetlemek için kullanın --property .

# Assert: button click updated the counter (smart value fallback — works for TextBlock, TextBox, etc.)
winapp ui invoke "Counter Button" -a $pid
winapp ui wait-for "Counter Display" -a $pid --value "Count: 1" -t 5000

# Assert: text input was accepted
winapp ui set-value "Search Box" "hello world" -a $pid
winapp ui wait-for "Search Box" -a $pid --value "hello world" -t 3000

# Assert: checkbox was toggled (use --property for specific UIA properties)
winapp ui invoke "Dark Mode" -a $pid
winapp ui wait-for "Dark Mode" -a $pid --property ToggleState --value "On" -t 3000

# Assert: navigation happened (new page appeared)
winapp ui invoke "Settings" -a $pid
winapp ui wait-for "Settings Page" -a $pid -t 10000

# Assert: dialog was dismissed (element disappeared)
winapp ui invoke "Close" -a $pid
winapp ui wait-for "Dialog Title" -a $pid --gone -t 5000

JSON çıkışıyla onaylama

Daha karmaşık onaylar için PowerShell veya jq ile kullanın --json :

ve search modunda wait-for için --json çıkış kodu sözleşmesi: Hiçbir öğe eşleşmediğinde (search) veya bekleme zaman aşımına (wait-for), komut stdout'a ({ "matchCount": 0, ... } veya { "found": false, "timedOut": true, ... }) tam olarak ayrıştırılabilir bir sonuç zarfı yazar ve çıkış kodu 1'i döndürür. Stderr modunda --json boş (günlükçü çıkışı gizlendi). Zarf alanlarında dallanma veya $LASTEXITCODEdaha ergonomik olduğuna bağlı olarak üzerinde dallanma.

# Assert: search found exactly one match
$result = winapp ui search "Submit" -a $pid --json | ConvertFrom-Json
if ($result.matchCount -ne 1) { throw "Expected 1 Submit button, found $($result.matchCount)" }

# Assert: element has expected properties
# inspect --json returns { windows: [{ hwnd, title, elements: [...] }] };
# each window's elements[] is the nested tree (children rendered via .children).
$tree = winapp ui inspect "Counter Display" -a $pid --json | ConvertFrom-Json
$counter = $tree.windows[0].elements[0]
if ($counter.name -ne "Count: 3") { throw "Counter value wrong: $($counter.name)" }

# Read typed element state while preserving the legacy string property map
$property = winapp ui get-property "Counter Display" -a $pid --json | ConvertFrom-Json
if ($property.element.type -ne "Text") { throw "Unexpected type: $($property.element.type)" }
if ($property.element.isOffscreen) { throw "Counter is offscreen" }

JSON zarfları şunlardır:

  • inspect: { "depth", "interactive", "hideDisabled", "hideOffscreen", "windows": [...] }
  • search: { "matchCount", "hasMore", "matches": [...] }
  • wait-for: { "found", "waitedMs", "element"?, "timedOut" }
  • get-property: { "elementId", "element", "properties": { ... } }

Yazılan öğeler ve sayısal x, y, widthve heightöğelerini kullanırtype. Geometri fiziksel ekran piksellerindedir. 0,0,0,0UI Otomasyonu'nin bu projeksiyondaki boş/görüntülenmeyen UI dikdörtgenidir; isOffscreen ayrıdır, bu nedenle bir ekran dışı öğenin sıfır olmayan sınırları olabilir.

Her inspect --jsonwindows[] girdi ve status --json sonuç , scale (windowDpi / 96), dpiAwarenessve coordinateSpace: "physical-screen-pixels"içerirwindowDpi. Bunlar, hedef pencerenin koşulsuz izleyici DPI'sı değil DPI bağlamını açıklar: Windows, farkında olmayan bir pencere için 96'yı, sistem algılamalı bir pencere için sistem DPI'sini ve monitör algılamalı bir pencere için geçerli izleyici DPI'sini raporlar. HWND veya DPI bağlamı okunamıyorsa, komut sessizce 96 yerine başarısız olur. Bir işlemi en üst düzey pencereye sahip olmadan önce çözümlediğinde status , hwnd bir 0 pencere var olana kadar DPI alanları atlanır. İşlem genelinde inspect, seçilen hedef pencere hızlı başarısız olmaya devam eder; ağacı okunduktan sonra sonraki bir açılır pencere kaybolursa, windows[] kalan pencere ağaçları döndürülürken girdisi DPI alanlarını taşır dpiError ve atlar.

Her zarfın tam örnekleri için gönderilen winapp-ui-automation beceriye references/ui-json-envelope.md bakın.

Tam duman testi örneği

# 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