Automatizace uživatelského rozhraní

Zkontrolujte spuštění Windows aplikací z příkazového řádku a interakci s nimi. Používají se agenti AI a vývojáři pro testování, ladění a automatizaci uživatelského rozhraní.

Přehled

winapp ui poskytuje příkazy pro kontrolu a interakci s uživatelskými rozhraními aplikace Windows. Používá Windows model UI Automation (UIA). Funguje s libovolnou Windows aplikací – WPF (Windows Presentation Foundation), WinForms, Win32, Elektron a WinUI 3. Většina příkazů řídí aplikaci vzory UIA (bez injektáže vstupu). Výjimky vloží skutečný vstup: ui click/ui hover/ui dragpoužijte simulaci myši,ui touch/ui pen syntetizuje vstup dotykového ovládání a pera a ui send-keys syntetizuje vstup klávesnice – pro ovládací prvky a scénáře, které vzory UIA nemohou řídit.

Important

Požadavek interaktivní plochy (vstupní injektáže sloves).click, hover, , dragtouch, , penscroll --wheel, a send-keys --via send-input syntetizovat vstup na úrovni operačního systému, takže potřebují odemknutou interaktivní plochu s cílovým oknem v popředí. Na uzamčené pracovní stanici nebo zabezpečené ploše (LogonUI/UAC) nemůžou rychle vkládat a selhat no_interactive_desktop (liší se od zvýšení neboforeground_not_target případů). touch / pen kromě toho odmítnout, pokud se nepřeloží žádné okno (no_target), souřadnice mimo cílové okno je nefaktální upozornění ( warnings[] položka pod --jsonnebo řádek upozornění v textovém režimu) a injektáž pokračuje – v souladu s příkazy myši. Všechno ostatní – inspect, search, , get-property, get-value, set-valuescroll --direction/--towait-forinvoke– řídí aplikaci vzory UIA a je bezobjemná/uzamčená relace přátelská. screenshot je výjimkou mezi nevkládanými příkazy: trvá výhradní otáčení a jeho zachycení může potřebovat použitelnou interaktivní plochu, protože modul obnoví minimalizovaný cíl a vrátí se do popředí, když je snímek snímku nedostupný nebo --capture-screen se použije. Preferujte příkazy vzoru UIA v CI; zarezervujte příkazy injektáže pro scénáře, které skutečně potřebují skutečný vstup. Před vložením gesta příkazy znovu přeloží cílový prvek a odmítne, target_moved pokud se stále animuje nebo přemísťuje, místo aby vstup přistál na prázdném místě.

rychlé zprovoznění

# 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

Spuštění automatizace uživatelského rozhraní v sandboxu Windows

Pokud chcete zachovat automatizaci mimo plochu, přidejte --on sandbox je do příkazů spuštění a uživatelského rozhraní:

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

--detach vrátí po startu; bez něj počká, run až se aplikace ukončí. Zachovejte --on sandbox všechny příkazy hosta, včetně těch, které používají PID nebo úchyt okna. Viz Windows spuštění sandboxu pro požadavky klientů, stručné nastavení a opětovné připojení změn zaměření, koordinace pracovních postupů a doručování výstupu hostitele.

Dotazy s vymezeným oborem a typem

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-propertya get-valuewait-for přijměte tyto volitelné filtry. Selektor a každý zadaný filtr musí odpovídat stejnému prvku:

  • --root <selector> hledá pouze potomky jednoho jedinečně odpovídajícího kořene, nikdy samotného kořenového adresáře. K nejednoznačnosti použijte AutomationId nebo slug.inspect Kořen, který odpovídá více prvkům, selže, ambiguous_selectori když je jedna shoda vyvolán. Chybějící kořen nevygeneruje žádné shody. Jakmile se kořen najde, dotazy neprohledat nesouvisející automaticky otevíraná okna, i když se neshodují žádné potomky. Dotazy nejsou omezeny hloubkou inspectzobrazení.
  • --type <control-type> odpovídá typu ovládacího prvku UIA a ignoruje malá a velká písmena. Jedinými aliasy jsou TextBox → Edit a TextBlock → Text. Neznámé názvy (včetně číselných ID a výrazů se zástupnými znamény) nezdaří s chybou invalid_arguments.
  • --class-name <literal> odpovídá celému uživatelskému rozhraní UIA ClassNameposkytovatele , ignoruje velká a malá písmena. Nejedná se o podřetěžce, zástupný znak ani regulární výraz. Slouží get-property --property ClassName ke zjištění hodnoty zprostředkovatele. Název třídy se nemusí shodovat s typem ovládacího prvku UIA.

Filtrované dotazy používají zobrazení ovládacího prvku UIA, stejné zobrazení, které inspectukazuje . Uzly zprostředkovatele vystavené pouze v nezpracovaných zobrazeních se nevrátí; slouží inspect k vyhledání ovládacího prvku obsahujícího ovládací prvek a jeho selektoru.

Všechny oficiální typy 41 jsou podporovány: Button, , Calendar, ComboBoxCheckBox, , Edit, Hyperlink, , ListTitleBarSliderSpinnerScrollBarTabStatusBarThumbGroupDataGridCustomTreeItemTreeDataItemToolTipToolBarTextDocumentTabItemRadioButtonSplitButtonHeaderItemHeaderTablePaneSeparatorSemanticZoomListItemMenuBarAppBarMenuMenuItemProgressBarWindowImage

wait-for Přeloží kořenový selektor znovu při každém hlasování, takže kořenový adresář se může objevit po spuštění příkazu. Chybějící --gonekořen znamená, že neexistuje žádný odpovídající potomek; nejednoznačný kořen je chyba, ne úspěch. Přerušené vyhledávání není důkazem o nepřítomnosti: pokud je prvek odebrán během vyhledávání nebo nahrazen před čtením --value , další kontroly hlasování znovu; jiné vyhledávání nebo chyby čtení příkaz selžou. -w <HWND> omezuje zjišťování kořenového adresáře na strom UIA daného okna. Díky -anástroji root discovery můžete také najít automaticky otevíraná okna aplikace. Přesná kořenová id automationid mají přednost před shodami podřetěděných řetězců ve všech těchto oknech; více přesných shod stále selhává s ambiguous_selector.

Kořenový slug vybere tento prvek i v případě, že má jiné okno stejné AutomationId. Pokud je vybraný kořen nahrazen, jeho starý slug již neodpovídá; Pokud chcete, aby dotazování sledovalo nahrazení, použijte kořenový adresář AutomationId nebo název.

Pokud jsou k dispozici filtry, příkazy, které čtou jeden prvek, selžou, ambiguous_selector pokud zbývá více než jeden prvek, zužte filtry nebo použijte jedinečný slug. Přesná hodnota AutomationId zachovává prioritu před shodami podřetěděných řetězců v rámci filtrovaného oboru. Vynechání všech tří možností zachová stávající chování dotazu.

Koordinace souběžných pracovních postupů uživatelského rozhraní

Windows má pouze jedno okno popředí, jeden fokus klávesnice, jeden kurzor a jeden vstupní datový proud. Když se dva winapp ui pracovní postupy spustí na stejné přihlášené ploše najednou, můžou od sebe odcizit fokus, zavřít nabídku, kterou právě otevřeli, nebo přesunout cíl mimo čekající kliknutí.

Rozhodčí řízení je vždy zapnuté. Každý winapp ui příkaz, který se dotkne fyzické plochy, se otočí, bez nastavení a způsob, jak ho vypnout, takže dva agenti nikdy nebudou moct zadávat do oken ostatních. Příkazy jen pro čtení stále běží souběžně.

Kontinuita mezi příkazy je opt-in. Ve výchozím nastavení je každý příkaz samostatným jedním snímkem: počká, udělá svou práci a uvolní plochu okamžitě. Pokud chcete zachovat plochu napříč několika příkazy, dejte jim stejné ID pracovního postupu:

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

Co potřebujete vědět:

  • ID pracovního postupu pojmenovává jeden logický pracovní postup – ne nutně celý agent, a ne nutně jednu aplikaci. Použijte stejnou hodnotu pro spolupracující příkazy (záznam plus kliknutí, které by mělo zachytit); pro nezávislé pracovní postupy používejte různé hodnoty, i když jeden agent spustí obojí.
  • Bez ID je každý příkaz nezávislý na jednom snímku. Stále rozhoduje, ale banky žádné odkladu a ruce plochu mimo okamžik, kdy skončí. Dva příkazy no-id jsou samostatné pracovní postupy i při spuštění ze stejného prostředí.
  • Nové prostředí a adaptivní hostitelé musí vložit stejnou hodnotu. Pokud každý příkaz běží v novém prostředí , což je způsob, jakým většina agentů volá, funguje – jediná věc, která je může seskupit, je explicitní WINAPP_UI_WORKFLOW_ID předání do každého spolupracujícího volání.
  • Čtyřsekundová grace chrání těsné nárazy, ne modelování důvod. Pracovní postup s ID se zachová tak dlouho, dokud se další příkaz spustí během čtyř sekund. To pokrývá příkazy back-to-back v jednom skriptu; jeho platnost záměrně vyprší, když model přemýšlí. Je to záložní, když nemůžete říct, že jste hotovi – když můžete, spusťte winapp ui yield místo čekání na něj.
  • Adaptivní pracovní postupy musí znovu inquire, revalidate a replay. Po odůvodnění jiného pracovního postupu se může použít plocha, takže znovu otevřete nabídku, znovu vyřešte prvek a pak jednat. Posílejte známé sekvence typu end-to-end jako jeden těsný skript, a nedržíte plochu, zatímco si myslíte.
  • Řazení je nejprve spřažení vlastníka, pak FIFO mezi ostatními. I když je pracovní postup aktivní nebo uvnitř jeho odkladu, může dál vydávat příkazy, i když už čekají jiné pracovní postupy. Po spuštění winapp ui yield nebo vypršení odkladu se čekající pracovní postupy obsluhují v přísném pořadí příjezdu. Průběžná aktivita podle jednoho pracovního postupu proto může zpozdit další po neomezenou dobu.
  • Není žádný tvrdý čepice. Dlouhý skript, nevázaný záznam nebo smyčka selhání může blokovat další ztlumené pracovní postupy.
  • Zrušení nebo ukončení procesu je obnovení pro zablokovaný živý pracovní postup. Příkazy čekající po jedné sekundě vytisknou stav a lze je zastavit Ctrl+C, což ukončí 130.
  • Spolupracují pouze kompatibilní aktualizované binární soubory. Starší winapp buildy předejdou tuto funkci a nejsou koordinované. Kód volající model UI Automation balíčky NuGet přímo je mimo tuto záruku – koordinace se nachází v rozhraní příkazového řádku, ne v balíčcích.

Které příkazy čekají na řadu:

Chování Commands
Spouští se souběžně (nikdy nečekejte) status, list-windows, inspect, , searchget-property, get-value, , get-focusedwait-for
Čeká na to, ale nikdy nepřebere plochu. set-value, scroll-into-view, , scroll --direction/--torecord
Čeká na závrat a vezme výhradně plochu. invoke, click, , drag, scroll --wheelhover, touchpenfocus, , send-keysscreenshot

Prostřední řádek je ten, který stojí za pochopení. set-valuea scroll-into-view--toscroll --direction/řídit vzory UIA místo popředí, takže zůstanou bezobrazné/uzamčené relace přátelské a nikdy nikoho nezablokují v používání plochy. Ale změní to, co aplikace zobrazuje, takže počká za jiným pracovním postupem místo úprav pole nebo posouvání seznamu mimo kliknutí někoho jiného.

V jednom pracovním postupu se překrývají s jinou sdílenourecord prací – to je způsob zachycení set-value volání, která nahrává. Ignorují své vlastní pracovní postupy dopředu bariéry: dřívější DesktopExclusive příkaz stejného pracovního postupu (a click, a screenshot) je stále blokuje, přesně tak, jak blokuje každý pozdější příkaz, takže kliknutí a mutaci, která následuje za ním, zůstane v pořadí, v jakém jste je napsali.

screenshot vždy zařadí fronty na výhradní turn. Ne každý záznam ruší plochu – běžné viditelné okno zachycené prostřednictvím Windows Graphics Capture ne – ale modul obnoví cíl, pokud je minimalizovaný, a vrátí se do popředí, když snímek snímku není k dispozici nebo --capture-screen přečte živou obrazovku. Tyto potřeby stačí, když je zachycení v cestě, takže příkaz se otočí dopředu, než odhadne. Když složí několik oken, zachytí je všechny pod jedním exkluzivním turnem, takže uložený obrázek je jediný konzistentní moment, a nikoli kombinace před a po. Kódování a zápis souboru se provádí po uvolnění plochy.

--capture-screen potřebuje přesně jedno okno. Zachytávání živých obrazovek zaznamenává vše, co je ve skutečnosti na předním místě, a může to být jenom jedno okno. Když okno vyberete explicitně tak -w <hwnd> , aby byla přesně jedna oblast – pixely uvnitř hranic okna, včetně jakéhokoli dialogového okna nebo překrytí, které je na něm viditelné, což je důvod, proč si obrazovku přečíst na prvním místě. Pokud -a se shoduje s několika okny nejvyšší úrovně nebo vlastněnými okny, neexistuje takový výběr, takže příkaz selže před invalid_arguments zachycením čehokoli, než bojovat proti popředí. Spusťte winapp ui list-windows -a <app> a zkuste to znovu a -w <hwnd>vložte --capture-screen všechna okna z vlastního obsahu.

record sdílí svůj tah, takže vstup stejného pracovního postupu může prokládat s zachycením – tedy jak zaznamenáte pracovní postup, který řídí aplikaci. Dvě upozornění:

  • Bez recordID pracovního postupu je vlastníkem jednoho snímku, takže blokuje každý druhý pracovní postup po celou dobu trvání. Pokud chcete nahrávat a současně kliknout, zadejte oba příkazy stejné WINAPP_UI_WORKFLOW_ID.
  • Na hostiteli bez podpory zachytávání snímků se záznam vrátí zpět do PrintWindow, jehož obnovení prázdného rámce může v každém okamžiku okno vysunout. Tam je plocha uložena pro celou nahrávku a příkaz říká tak ve svém výstupu; i vstup stejného pracovního postupu počká.

Může se zobrazit chyba: invalid_ui_workflow_id (proměnná je nastavená, ale je prázdná nebo více než 256 znaků), desktop_coordination_unavailable (stav koordinace je nečitelný a nelze ho bezpečně znovu vytvořit nebo ji zapsat novější winappqueue_capacity_exceeded ), (64 příkazů z jiných pracovních postupů už čeká – limit počítá živé cizí číšníky, ne procesy, které jste spustili, takže položky patřící příkazům, které byly ukončeny nebo zabity, nezabírají slot, a vlastní příkazy pracovního postupu se zařadí do fronty namísto tohoto limitu), ui_turn_busy (yieldzatímco váš vlastní pracovní postup má stále spuštěný příkaz) a cancelled (Ctrl+C při čekání, ukončovací kód130).

Uvolnění počátku turnu: winapp ui yield

Čtyřsekundová odkladu je záložní: zachová plochu rezervovanou, když nemůžete říci, že jste hotovi. Když to můžete říct, řekněte to yield – ruce na plochu okamžitě místo toho, aby všichni ostatní čekali na milost, kterou nikdo nepotřebuje.

$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
  • Příkazy s jedním snímkem by neměly vůbec nastavit ID pracovního postupu. Bez jednoho už každý příkaz uvolní plochu v okamžiku, kdy skončí, a není nic, co by bylo možné přinést.
  • Pracovní postupy s více kroky by měly být při jejich dokončení výnosné, zejména pokud mohou čekat jiné pracovní postupy. Stojí jeden rychlý příkaz a odebere čtyřsekundový stánek od ostatních.
  • Je idempotentní. Dává se dvakrát nebo po vypršení odkladu, úspěšně a hlásí { "released": false } – to je normální konec skriptu, nikoli selhání.
  • Nikdy neuvolní jiný pracovní postup. Pokud někdo jiný drží plochu, nebo to nikdo nedělá, je to no-op.
  • ui_turn_busyPokud má váš vlastní pracovní postup stále spuštěný nebo zařazený do fronty – záznam, řekněme. Uvolnění pod tímto příkazem by předalo plochu uprostřed příkazu, takže nic není uvolněno a spuštěný příkaz není ovlivněn. Počkejte na to nebo ho zastavte a pak znovu ho vyvolejte.
  • To vyžaduje WINAPP_UI_WORKFLOW_ID. Bez jednoho se to nezdaří s invalid_arguments.
  • Nevybere žádnou aplikaci a žádný selektor: vrátí rezervaci, ne okno, takže bude fungovat i po zavření aplikace.

Čekající příkaz se probouzí tím, kdo místo dotazování uvolní plochu, takže fronta stojí téměř nic, když čeká a předání je okamžité. Každý číšník také občas znovu zkontroluje plochu, což je to, co obnoví plochu, když se proces ukončí a nikdy nic nepublikuje: příkaz v čele fronty vypadá každou půl sekundu a příkazy za ním – které se nedají spustit před tím, než hlava stejně udělá – každých několik sekund.

Cílení aplikací

Podle názvu procesu

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

Podle názvu okna

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

Autor: PID

winapp ui inspect -a 12345

Podle HWND (stabilní – přežije změny tabulátoru/názvu)

# 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

Slouží -a ke zjišťování pro -w stabilní cílení. Pokud -a odpovídá více oknům, příkaz je zobrazí se seznamem HWND, které můžete vybrat.

Selektory

Cílové prvky pomocí selektoru zobrazeného ve [brackets] výstupu kontroly a hledání Existují tři typy selektorů:

Selector Význam Example
MinimizeButton AutomationId (zobrazené, pokud je jedinečné – stabilní, upřednostňované) winapp ui invoke MinimizeButton -a myapp
btn-close-d1a0 Sémantická slug (zobrazená v případě, že žádné jedinečné ID automatizace) winapp ui invoke btn-close-d1a0 -a myapp
Submit Vyhledávání ve formátu prostého textu proti name/AutomationId (podřetětět bez rozlišování malých a velkých písmen) winapp ui invoke Submit -a myapp

Selektory AutomationId jsou identifikátory sady vývojářů (AutomationProperties.AutomationId v JAZYCE XAML). Pokud je Id automatizace jedinečné v celém stromu inspect uživatelského rozhraní a search zobrazí ho přímo jako selektor – ty přežijí změny rozložení, lokalizaci a restrukturalizaci stromu.

Selektory slug (např. ) se vygenerují, btn-close-d1a0pokud neexistuje žádný jedinečný identifikátor AutomationId. Formát: prefix-name-hash. Hodnota hash ověří identitu elementu, ale po změně uživatelského rozhraní může být zastaralá.

Kontrola výstupního formátu

Příkaz inspect zobrazí strom elementu s barevným výstupem (selektor v azurové barvě, název zeleně, metadata šedě):

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

První slovo na každém řádku je selektor – použijte ho s dalšími ui příkazy. Pokud má prvek jedinečný AutomationId, použije se přímo (např TabView. , NewTabButton). Pokud neexistuje žádný jedinečný identifikátor AutomationId, použije se vygenerovaný slug (např. tab-newtab-5f5b).

Sémantické slugy

Slugy používají formát: kde: prefix-normalizedname-hash

  • prefix — zkratka typu 3 písmena (btn, txt, chk, cmb, itm, tab, img, lbl, pn, win, grp, lnk, mnu atd.)
  • normalizedname – malá písmena alfanumerická z AutomationId (preferovaný) nebo Název, maximálně 15 znaků
  • hash – šestnáctkový algoritmus 4 char hodnoty runtimeId elementu (ověření identity elementu)

Slugy jsou bezpečné prostředí (bez speciálních znaků), jedinečné a lze je použít přímo jako argumenty. Bez filtrů dotazů poskytuje hodnota hash detekci neagrese – pokud byl prvek nahrazen, získáte: "Prvek mohl být změněn. Znovu spusťte kontrolu." Filtrované dotazy najdete v tématu Vymezený a typový dotaz.

Prvky bez názvu nebo Id automation zobrazují pouze předponu + hash (např. pn-c8a3).

Nejednoznačnost více shod

Slugs from inspect/search output are unique, but can change across layout changes – use them over plain type names or text when multiple matches. Když je selektor nejednoznačný, rozhraní příkazového řádku vytiskne všechny shody s jejich slugy, abyste mohli vybrat ten správný a znovu spustit s tímto slugem.

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

Použití prostého textu k hledání prvků – nevyžaduje se žádná zvláštní syntaxe:

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

Když hledání textu odpovídá více prvkům (například SettingsExpander, kde Group, Button a Text všechny sdílejí stejný název), rozhraní příkazového řádku automaticky vybere jediný vyvoláný prvek. Pokud je více vyvoláno, zobrazí se seznam všech shod se slugy.

Pro nevolitelné výsledky hledání (např. TextBlock uvnitř tlačítka) se při hledání automaticky zobrazí nejbližší vyvoláný nadřazený prvek – nadřazený prvek, se invokekterým můžete použít . To funguje pro všechny selektory vyhledávání:

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

Selektor povrchu lze použít přímo:

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

Commands

stav

Připojte se k aplikaci a zobrazte informace o připojení.

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

Zkontrolovat

Zobrazte strom prvků uživatelského rozhraní. Výstup zobrazuje sémantické slugy s odsazením mezer pro hierarchii:

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

Příklad výstupu (výchozí):

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)

Příklad výstupu (--interactive – pouze vyvolání prvků, plochý seznam):

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)

Prvky můžou zobrazovat tyto značky stavu:

  • [on] / [off] / [indeterminate] — přepínací/zaškrtávací políčko
  • [collapsed] / [expanded] — rozbalení/sbalení stavu pro stromy, pole se seznamem, položky nabídky
  • [scroll:v] / [scroll:h] / [scroll:vh] — posuvný kontejner (svislý, vodorovný nebo oba)
  • [offscreen] — prvek není na obrazovce viditelný.
  • [disabled] — prvek není povolen.
  • value="..." — aktuální textový obsah pro upravitelné prvky (pokud se liší od názvu)

Vyhledání prvků odpovídajících selektoru Výstup ukazuje sémantické slugy:

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

Příklad výstupu:

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

Slugy zobrazené ve výstupu (např btn-minimize-d1a0. ) lze použít přímo s jinými příkazy:

winapp ui invoke btn-minimize-d1a0 -a notepad

get-property

Čtení hodnot vlastností z elementu Zahrnuje stav specifický pro vzor (ToggleState, Value, IsSelected atd.).

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

V názvech vlastností se rozlišují malá a velká písmena. Neznámý název se nezdaří s invalid_arguments položkou --json; vynecháte --property výpis vlastností, včetně všech šesti atributů formátování textu níže. wait-for --property používá stejné názvy s rozlišováním velkých a malých písmen a před dotazováním odmítne neznámé názvy.

Formátování textu celého dokumentu

Formátování se čte v celém dokumentu TextPattern prvku, nikoli v aktuálním výběru nebo stříšce. Čtení nemění fokus ani výběr.

Property Jednotná hodnota (vrácená jako řetězec)
FontWeight Číselná váha, například "400" (normální) nebo "700" (tučné)
FontName Jméno rodiny písem, například "Courier New"
FontSize Velikost v bodech, například "15.5"
ForegroundColor Desetinná Windows COLORREF (0x00BBGGRR), například "3678732" pro RGB(12, 34, 56)
IsItalic "True" nebo "False"
StrikethroughStyle Styl text-decoration numeric UIA, například "0" (žádný) nebo "1" (jeden)

Čísla používají invariantní formátování (desetinná čárka bez ohledu na národní prostředí). Každý atribut může místo toho vrátit:

Hodnota Význam a další krok
"Mixed" Formátování se v dokumentu liší. Nechořujte s ní jako s jednotnou hodnotou; tento příkaz neodkazuje na jednotlivé rozsahy textu.
"NotSupported" Zprostředkovatel TextPattern dokumentu nehlásí tento atribut. Zkontrolujte podporu přístupnosti aplikace.
"Unavailable" Element nemá žádný TextPattern. Použijte inspect nebo search vyhledejte jeho text nebo prvek dokumentu.

Při výpisu všech vlastností zůstanou základní vlastnosti uložené v mezipaměti k dispozici, pokud nelze přeložit žádný živý prvek, a hodnota chybného formátování se vynechá bez zahození jiných vlastností. Tato vynechání se protokolují jako upozornění. Požádejte o konkrétní vlastnost formátování, aby se místo vynechání zobrazila chyba.

Selhání poskytovatele zůstávají chyby, nikoli "Unavailable". Zkontrolujte stale_elementaplikaci znovu a zkuste to znovu pomocí aktuálního selektoru.

Obálka JSON zahrnuje elementIdtyp a elementřetězcovou hodnotu properties. Existující vlastnosti, včetně BoundingRectangle, zachovat jejich formáty. Například část formátování properties je:

{
  "FontWeight": "700"
}

screenshot

Zachyťte okno nebo prvek jako PNG.

winapp ui screenshot -a notepad                     # saves screenshot.png in cwd
winapp ui screenshot -a notepad --output my.png     # custom filename
winapp ui screenshot --quiet -a notepad -o my.png   # save without informational output
winapp ui screenshot -a notepad --json              # returns file path as JSON
winapp ui screenshot -w 131906                      # target specific HWND (+ its dialogs)
winapp ui screenshot txt-searchbox-e5f6 -a myapp          # crop to element bounds
winapp ui screenshot -w 131906 --capture-screen     # one screen region, with visible overlays in place; foregrounds window
winapp ui screenshot -a myapp --focus               # bring window to foreground first, then capture (default WGC path)

Bez selektoru prvků kombinuje výchozí zachytávání více oken do jednoho označeného složeného PNG vedle sebe, nikoli samostatných souborů. -a podle názvu procesu nebo PID zahrnuje okna aplikace a vlastní okna. Shoda založená na -a názvu vybere jedno odpovídající okno a vlastní okna. -w Explicitně vybere jedno okno a vlastní okna, ne každé okno v procesu. Vlastní dialog nebo popisek se proto může zobrazit jako vlastní panel, i když explicitně vyberete hlavní HWND. Selektor prvku se ořezá na tento prvek místo vytváření oken.

--quiet potlačuje informační výstup pro jednoohlásné i složené snímky, včetně uložené cesty. Upozornění a diagnostika selhání zachycení zůstávají viditelná. Místo toho použijte --json , pokud potřebujete cestu k souboru a dimenze jako strukturovaný výstup.

V --on sandboxpoužádce --output pojmenujte cíl hostitele. Úspěšný prostý výstup a --json sestava cesty hostitele po doručení image.

Výchozí cesta zachycení používá Windows. Graphics.Capture (WGC), čtení skutečného složeného povrchu DWM – zachování zaoblených rohů, průhlednosti a práce i v době, kdy je okno odlehlé jinými windows. Pokud není WGC k dispozici (starší Windows sestavení), rozhraní příkazového řádku se vrátí zpět do PrintWindow.

Použijte --capture-screen -w <hwnd> , když potřebujete viditelné automaticky otevírané okno nebo popisy v jejich pozicích na obrazovce, včetně překryvů, které nejsou vlastněny cílovým oknem. Přečte oblast obrazovky daného okna místo psaní označených panelů a nejprve okno přenese do popředí. V -apřípadě , že vyžaduje přesně jedno odpovídající okno; pokud se několik oken nejvyšší úrovně nebo vlastněných oken shoduje, použijte winapp ui list-windows -a <app> a opakujte akci s -w <hwnd>. Můžete --focus použít, pokud chcete okno jenom na popředí bez přepínání režimů zachycení (např. aby se zajistilo, že snímek obrazovky odpovídá tomu, na co se právě dívá uživatel).

Vzhledem k tomu, že řadič domény obrazovky zachytí vše, co je ve skutečnosti na přední straně, --capture-screenověří cíl, který bezprostředně před zachycením dosáhne popředí a selže, foreground_not_target pokud ne (prevence krádeže fokusu, výzva nástroje Řízení uživatelských účtů nebo jiné okno, které se aktivuje samotné). V takovém případě není napsaný žádný obrázek – dříve příkaz ukončil hodnotu 0 a vrátil obrázek nesprávného okna. ui record --capture-screen použije stejnou kontrolu před prvním snímkem.

záznam

Zaznamenejte okno nebo oblast elementu do souboru H.264 MP4. Upřednostněte pozitivní --duration-sec pro bezobslužné skripty. Bez doby trvání bude nahrávání pokračovat až do Ctrl+C nebo, pro přesměrovaný stdin, nový řádek nebo EOF. Npm uiRecord a targetRecord pomocní správci vyžadují celé číslo durationSec od 1 do 86400; jejich přerušený signál se zruší vynuceně místo řádné dokončení záznamu.

# 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

Možnosti:

  • --duration-sec N — Zaznamenejte po dobu N sekund. Výchozích 0 záznamů, dokud se nezastaví.
  • --fps N — Cílové snímky za sekundu (výchozí 15).
  • --max-edge N — Snížení měřítka tak, aby nejdelší hrana byla maximálně N pixelů (0 = bez snížení měřítka).
  • --capture-screen — Zachytávání z řadiče domény obrazovky (zahrnuje překryvné nebo automaticky otevírané okno; popředí okna).
  • --output <path> — Výstupní cesta MP4. Výchozí hodnota je recording-<timestamp>-<guid>.mp4.
  • --overwrite – Po dokončení nového dokončení nového záznamu nahraďte stávající výstupy záznamu. Bez něj se existující výstupy zamítnou.
  • --frames — Psát časového razítka JPEG důkaz do <output-name>.frames. Podporuje 1-30 fps a --max-edge 64-4096 (výchozí 1280). Data rámce jsou omezena na 1 GiB; mp4 pokračuje, pokud je dosaženo limitu.

Artefakty rámečku s možností čtení agenta:

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

frames.ndjson má jednu čáru na vzorek s sampleIndexmonotónní elapsedMs, MP4 relativní mediaTimeMs, imageIndex, , filea changed. Po sobě jdoucí identické vzorky s identickými pixely znovu používají předchozí formát JPEG s kvalitou 85.

manifest.json zaznamenává požadavek, časování, stav MP4, rozměry obrázků a stav (complete, partialnebo truncated). Zkrácené časování pokrývá zachovanou předponu, zatímco video popisuje kompletní MP4.

Zvolte novou výstupní cestu, pokud nemáte v úmyslu nahradit záznam --overwrite. Bez něj buď existující video nebo jeho spárovaný .frames adresář blokuje záznam, i když vynecháte --frames. Předchozí mp4 zůstane nedotčené, pokud se nový záznam nezdaří. Při úspěšném nahrazení se předchozí adresář rámce zachová jako <output-name>.frames.previous-<id>, i když nový záznam vynechá --frames. Před opakováním zachovejte částečné důkazy a postupujte podle hlášení recoveryHint . Pokud se dokončení MP4 nezdaří, zachované snímky lze publikovat v části <output-name>.frames.partial-*. Artefakty rámce obsahují nešifrovaný obsah obrazovky; zpracujte je jako snímky obrazovky nebo video.

V --on sandboxpřípadě, že se do hostitele doručí adresář MP4 i adresář rámce, včetně výchozích výstupů, pokud --output je tento parametr vynechán. Podívejte se na záznam sandboxu pro přerušené nahrávky a zachycení na celé ploše.

Režimy zachycení (hlášené v poli JSON mode ):

  • wgc— Windows Graphics Capture (výchozí; funguje, když je okno odlehlé).
  • printwindow — PrintWindow GDI (náhradní, pokud není WGC v tomto systému nebo relaci k dispozici; znovu spusťte --capture-screen pro použití řadiče domény obrazovky).
  • screen — Obrazovka DC přes --capture-screen (zahrnuje překryvné nebo automaticky otevírané okno; přenese okno do popředí).

Výstup JSON (--json):

  • stdout: Konečný výsledek záznamu, včetně četnosti, důvodu zastavení, volitelného frameArtifactszáznamu a upozornění.
  • stderr: Jeden objekt JSON na řádek: recording-started událost za prvním snímkem následovaná chybou, pokud se záznam později nezdaří. Cesty rámců jsou zahrnuty pouze v případech, kdy je aktivní výstup rámce.

Kódy chyb:

  • element_not_found — Selektor se neshodoval.
  • ambiguous_selector — Selektor odpovídal více prvkům; použijte navrhovaný slug.
  • invalid_arguments — Hodnota možnosti je neplatná.
  • output_exists — Záznamový výstup již existuje a nelze jej nahradit požadovanými možnostmi.
  • frame_output_failed – Ani jeden artefakt nelze zachovat po selhání výstupu rámce.
  • partial_output — Dokončeno pouze jeden artefakt; kontroly partialOutput a recoveryHint.

Známé omezení: Záznam prvku uvnitř automaticky otevíraného okna může zachytit podkladové okno. Zaznamenejte celé okno nebo postupujte podle pracovního postupu překryvného snímku obrazovky pro obrázek. Viz č. 646.

volat

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

Použijte --action , když test musí provést konkrétní operaci s přesně vybraným prvkem. Nikdy se nepokusí jiný vzor nebo vyvolání nadřazeného objektu, i když požadovaná akce selže. Ovládací prvek podporující vyvolání i výběr se vybere, nevyvolá se s --action select. S --action, slug cíl přesně jeden prvek; prostý text nebo AutomationId selektor, který odpovídá více než jednomu prvku, se zavře s nenulovým ukončovacím kódem místo toho, aby se chovaly na první shodě, takže předejte slug, když inspect/search je název nejednoznačný.

Action Operation
invoke InvokePattern.Invoke
select SelectionItemPattern.Select
toggle TogglePattern.Toggle, přesně jednou
toggle-on / toggle-off Read ToggleState; úspěšné beze změny již správného stavu, jinak přepněte a ověřte
expand / collapse ExpandCollapsePattern.Expand / Sbalit

Pro toggle-on a toggle-off, počáteční Indeterminate stav umožňuje maximálně dva přechody, kontrola stavu za každou. Ostatní počáteční stavy umožňují jeden přechod. Pokud požadovaný stav není dosažen, příkaz se nezdaří a nebude pokračovat v přepínání. Neúspěšné ověření může ovládací prvek nechat změněný; přečtěte si, ToggleState než se rozhodnete, co dělat dál.

Bez --action, stávající automatické chování je beze změny: try InvokePattern, TogglePattern, SelectionItemPattern, then ExpandCollapsePattern (expand), s vyvolání-nadřazené opakování v případě potřeby.

Nepodporovaná akce selže s nenulovým ukončovacím kódem --jsona se strukturovanou chybou na stderru. Zkontrolujte vybraný ovládací prvek a zvolte akci, která podporuje, nebo explicitně cílit na zamýšlený nadřazený prvek. Kód JSON pro úspěch zahrnuje requestedAction a performedActionviz referenční informace k JSON.

click

Klikněte na prvek na souřadnicích obrazovky pomocí simulace myši. Tuto možnost použijte pro ovládací prvky, které nepodporují InvokePattern (například záhlaví sloupců, položky seznamu).

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

Stejně jako ostatní vstupní příkazy přináší cíl na popředí a click (na uzamčené/zabezpečené ploše, no_interactive_desktop pokud fokus foreground_not_target nemohl být přenesen) místo kliknutí na nesprávné okno. Také znovu vyřeší prvek těsně před tlačítkem dolů: po umístění kurzoru provede jednu konečnou kontrolu pozice, takže nepřetržitě pohybující se nebo animační cíl selže místo target_moved nahlášení úspěchu po kliknutí na prázdné místo – hlášený úspěch znamená, že cíl byl stále na místě, když tlačítko zmizelo.

přetáhnout

Stiskněte tlačítko myši v jednom bodě, přejděte do jiného a uvolněte drag <from> <to>s , kde každý koncový bod je buď selektor prvků (přetáhne z/do středu elementu) nebo souřadnice x,yobrazovky přesně tak, jak je hlášeno winapp ui inspect. Směšte a shodujte volně (selektor→výběr, selektor→záznamy, koordy→záznamy).

Používá SendInput se s průběžnými přesuny, aby aplikace viděla realistický datový proud WM_MOUSEMOVE zpráv. Slouží k přeuspořádování a změně velikosti úchytů, posuvníků, kreslení plátna a přetažení.

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

Možnosti:

  • --right — Přetáhněte ho pravým tlačítkem myši místo levého tlačítka.
  • --hold-ms <ms> — Před přesunutím podržte tlačítko na začátku (výchozí hodnota: 0). Při <from> == <to> (bez pohybu) se provádí gesto stisknutí a podržení / dlouhé stisknutí .
  • --dwell-ms <ms> — Přebývat v cíli po přesunutí před uvolněním (výchozí hodnota: 0). Umožňuje vypustit cíle / sloučit překryvy , které rameno od udržitelného najetí myší (místo okamžiku, kdy kurzor dorazí) západky před tlačítkem nahoru.

Holé x,y jsou souřadnice obrazovky ve stejné sestavě prostoru winapp ui inspect/search a selektor se překládá na střed elementu – nejprve zkontrolujte, jestli chcete vybrat body.

Podobně jako send-keys --via send-input, drag vloží operační systém na souřadnice obrazovky po přenesení cíle do popředí. Pokud fokus nemůže být přenesen do cíle (např. prevence krádeže fokusu z procesu na pozadí), příkaz se nezdaří (foreground_not_target) místo přetažení nesprávného okna – fokus nebo první kliknutí na okno. Na uzamčené/zabezpečené ploše selže s no_interactive_desktopchybou . Každý koncový bod prvku se přeloží okamžitě před přetažením; pokud se stále přesouvá nebo reizing (animating target), příkaz selže místo target_moved přetažení na zastaralý bod. (Holé x,y koncové body se nedají znovu ověřit, takže se používají as-is.)

Dotyk

Vkládání syntetických dotykových gest pomocí rozhraní API pro injektáže ukazatele Windows Ukotvení kontaktu je buď selektor elementu (používá střed elementu), nebo explicitní souřadnici x,yobrazovky prostřednictvím --at (stejné sestavy prostoruwinapp ui inspect). Můžete ho použít pro interakce klepnutím nebo stisknutím a vícedotykových gest, která simulace myši nedokáže vyjádřit.

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)

Možnosti:

  • --gesture <g>— tap (výchozí), double-tap, long-press, swipepinch, , stretch.
  • --at <x,y> — Explicitní počáteční bod (souřadnice obrazovky). Výchozí hodnota je střed elementu selektoru.
  • --to-point <x,y>— Koncový bod pro swipe Má přednost před --direction.
  • --direction <right|left|up|down> — Směr potáhnutí prstem (výchozí: right). V kombinaci s --distance tím, jak vypočítat koncový bod, pokud --to-point není zadaný.
  • --distance <px> — Rozprostřený prst pro pinch/stretchpixely nebo potáhnutí prstem na pixelech.
  • --hold-ms <ms> — Podržte kontakty před zvedáním (doba blokování dlouhého stisknutí; výchozí hodnota je 500 ms, long-press pokud není nastavena).
  • --duration-ms <ms> — Doba klouzání pro pohybová gesta (potáhnutí/ připnutí/roztažení; výchozí hodnota 300).
  • --fingers <n> – Počet kontaktů (1–10; výchozí 1). pinch / stretch vždy používejte 2.

Bezpečnost injekce. touch odmítne vložení, pokud se nepřeloží žádný cílový popisovač okna a toto okno obsahuje popředí – selže, no_target pokud se nedá přeložit žádné okno, foreground_not_target pokud fokus nejde přenést nebo no_interactive_desktop na uzamčené/zabezpečené ploše. Každá souřadnice (střed prvku, explicitní --at/--to-pointa vygenerované body cest) se kontroluje proti obdélníku cílového okna; bod mimo okno se zobrazí jako upozornění, které není závažné (warnings[]položka v --jsontextovém režimu nebo řádek upozornění) a injektáž pokračuje – odpovídá slovesům myši (click/drag/hover/scroll), které se také vloží do souřadnic mimo okno. --fingers výše uvedených 10 je zamítnuto předem.

Poznámka k hardwaru. Dotykové ovládání dává přednost modernímu zařízení s syntetickým ukazatelem (CreateSyntheticPointerDevice(PT_TOUCH)) a vrací se ke starší InitializeTouchInjection/InjectTouchInput verzi rozhraní API. Pokud v aktuálním zařízení nebo relaci není injektáž podporována, příkaz zobrazí skutečný kód chyby Win32 (např. nepodporovaný) místo nahlášení nepravdivého úspěchu – považuje za nenulový konec jako "nedoručený dotyk".

relace Vzdálená plocha / virtuálních počítačů. V Vzdálená plocha (RDP) nebo některých relacích virtuálního počítače může operační systém přijmout syntetické dotykové ovládání (exit 0), aniž by se skutečně dostal do cílové aplikace. Když se zjistí vzdálená relace, touch připojí upozornění na nejistotu doručení – warnings[] položku v --jsontextovém režimu nebo řádek upozornění. / ✅exit 0 pak znamená , že volání injektáže bylo úspěšné, a ne to, že aplikace přijala vstup. Potvrďte účinek, když ui screenshot/ui inspect na tom záleží.

pero

Vkládání syntetických vstupů pera – klepnutí a tahy rukopisu – pomocí rozhraní API Windows syntetického ukazatele (CreateSyntheticPointerDevice(PT_PEN); Windows 10 1809+). Zaměřte se na střed prvku, explicitní --at bod nebo úplný --path tah rukopisu.

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

Možnosti:

  • --at <x,y> — Kontaktní bod pera (souřadnice obrazovky). Výchozí hodnota je střed elementu selektoru. Ignorováno při --path zadání.
  • --path "<x,y x,y …>" — Cesta tahu rukopisu jako dvojice oddělené x,y prázdnými znaky (jednobodová cesta je klepnutí).
  • --pressure <0.0–1.0> — Tlak pera (výchozí hodnota 0,5).
  • --tilt-x <deg> / --tilt-y <deg> — Úhly naklonění pera, −90 až 90 (výchozí hodnota 0).
  • --eraser — Místo špičky použijte konec gumy pera.
  • --duration-ms <ms> — Celková doba pohybu tahů v milisekundách distribuovaná jako interpolované snímky UPDATE v cestě (výchozí hodnota: ~10 ms na směrný bod). Pomocí tohoto postupu můžete určit, jak rychle se pero pohybuje od začátku do konce.

Bezpečnost injekce. Stejně jako touch, pen odmítá vkládat bez nenulového, popředí cílového okna (no_target / foreground_not_target / no_interactive_desktop) a kontroluje každý rukopisný bod proti obdélníku cílového okna, zobrazí všechny souřadnice mimo okno jako ne závažná upozornění (warnings[]v --jsontextovém režimu nebo řádek upozornění v textovém režimu), zatímco stále vkládání – v souladu s příkazy myši. Neplatné --pressure (mimo 0,0–1,0) nebo naklonění (mimo ±90°) jsou odmítnuty dopředu.

relace Vzdálená plocha / virtuálních počítačů. Směrování pera je obzvláště nespolehlivé nad Vzdálená plocha: Volání prostřednictvím injektáže může hlásit úspěch (ukončení 0), aniž by vstup pera dosáhl aplikace. Když se zjistí vzdálená relace, pen připojí upozornění na nejistotu doručení (warnings[] v --jsontextovém režimu nebo řádek upozornění), takže není omylem ✅ pro potvrzené doručení. Ověřte toky závislé na peru na místní interaktivní ploše.

Najetí myší

Přesuňte myš na střed prvku, aby se aktivovaly efekty přechodu myší (popisy, kontextové rámečky, stavy vizuálů). Používá SendInput se k realistickému pohybu myši s malými chutěmi a pak čeká na konfigurovatelnou dobu přemísťování.

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

Možnosti:

  • --dwell-time <ms> — Doba v milisekundách čekat po najetí myší na účinky (výchozí hodnota: 800, rozsah: 0–10000)

send-keys

Odesílání syntetického vstupu klávesnice – protějšku klávesnice .click UIA nemá žádný vzor injektáže klávesnice, takže to klesne do vrstvy Win32. Můžete ho použít pro navigaci pomocí klávesnice (šipky, klávesy Tab, Enter, Esc), klávesové zkratky (ctrl+c, alt+f4) a psaní do ovládacích prvků, které vyžadují události stisknutí kláves místo set-valueatomového zápisu.

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

Gramatika klíče (tokeny oddělené prázdnými znaky, uvozovky řetězců s více tokeny):

  • Pojmenované klíče — enter/return, tab,esc/escape , , spacebackspace, delete/delinserthomeendpageup/pguppagedown/pgdnup/down/left/rightf1f16apps– , , printscreen, . capslock
  • Sekvence – více tokenů se stiskne v pořadí: down down enter.
  • Modifikační komba — ctrl, shift, , altwin spojení s +: ctrl+shift+t, alt+f4.
  • Text literálu – jakýkoli token, který není známým klíčem, je zadaný znakem: hello. Sousední literály udržují mezeru mezi nimi, takže citovaná fráze jako "Hello world" je doslovné znění (mezera je zachována); literál, který obsahuje pouze + text, například C++ nebo a+b je zadán jako text, nikoli parsovaný jako pole se seznamem.
  • Explicitní doslovný řídicí znak – předpona tokenu k text= jeho zadání doslovně i v případě, že koliduje s názvem klíče nebo modifikačního klasifikátoru: text=enter místo stisknutí klávesy Enter zadá slovo "enter" a text=ctrl+a zadá literálový řetězec. Zrcadlí vk= řídicí; řídicí hodnota se stále sloučí se sousedními literálovými slovy (text=down low → "dolů"). Vzhledem k tomu, že tokeny jsou prázdné znaky rozdělené (a sousední literály se znovu spojí s jednou mezerou), použijte zpětné lomítko uvnitř text= hodnoty k zadání prázdných znaků, které by jinak nepřežily: \s → mezeru, \t → tabulátor, \n → nový řádek, \r → nový řádek, \\ → zpětné lomítko literálu. \n, \ra \r\n každý vloží jeden konec řádku (Enter / VK_RETURN), takže text=line1\nline2 oba text=line1\r\nline2 zadejte jeden nový řádek. Takže text=a\s\sb typ "a b" (dvojité mezery) a text=\shi udržuje úvodní mezeru. Nerozpoznaný řídicí znak (např. \x) je ponechán doslovně.
  • Literál celého argumentu (--verbatim) – pokud je celá datová část literálovým textem, předejte --verbatim místo zapouzdření každého tokenu znakem text=. Na rozdíl od normální cesty zachovává přesné vnitřní prázdné znaky (bez sbalení) vk=argument celé klíče ( bez/text=\s sbalení). Zadáte send-keys "down down enter" --verbatim tedy slova a send-keys "a b" --verbatim zachováte dvojité mezery. Řídicí znaky zpětného lomítka nejsou dekódovány v --verbatim režimu ( \s zadává se jako zpětné lomítko a znak "s"), použijte text= token, pokud potřebujete řídicí znak s řídicím znakem.
  • Nezpracované virtuální klíče – vk=0xNN (šestnáctkové) nebo vk=NN (desítkové) pro klíče bez popisného názvu.

Možnosti:

  • --target <selector> — Před odesláním klíčů zaměřte tento prvek (prostřednictvím UIA). Bez něj klíče přejdou na aktuálně zaměřený prvek aplikace.
  • --verbatim — Zadejte celý argument klíčů jako text literálu (bez klávesy, pole se seznamem nebovk=/text= parsováním) a zachovávejte přesné prázdné znaky. Celá forma argumentu řídicího znaku pro token text= .
  • --via <transport>– post-message (výchozí) příspěvkyWM_KEYDOWN/WM_KEYUP/WM_CHARdo fronty cílového okna. Je cílená na HWND a obchází uiPI (funguje napříč úrovněmi integrity). send-input vloží operační systém do SendInput celého okna a přejde do okna popředí.

Volba dopravy / známých limitů:

  • post-message je výchozí, protože obchází uiPI a nezávisí na popředí okna. Omezení: Nemůže aktivovat globální klávesové zkratky zaregistrované prostřednictvím WH_KEYBOARD_LL háků nízké úrovně (ty, které klepnou na vstupní upstream jakékoli fronty oken) a aplikace, které čtou nezpracovaný stav klíče prostřednictvím GetAsyncKeyState , nemusí sledovat uchovávané modifikátory. Automaticky se přeloží a publikuje do podřízeného okna cílového vlákna (prostřednictvím GetGUIThreadInfo) po popředí, takže klasické aplikace Win32/WinForms, jejichž ovládací prvky jsou samostatné podřízené okna, přijímají klíče bez ručního cílení na ovládací prvek. Aplikace WinUI 3 / UPW mají bez oken ovládací prvky XAML bez podřízeného HWND, takže publikované WM_CHAR/WM_KEYDOWN nemá nic k tomu, aby přistálo a je vyřazeno - po-zpráva je nemůže řídit (příkaz varuje a ukončuje 0); použijte --via send-input. (WPF (Windows Presentation Foundation) okna jsou single-HWND a směrují klíče k interně zaměřenému prvku, takže post-message funguje tam.)
  • send-inputvytváří plně skutečný vstup (modifikátory viditelné pro GetAsyncKeyState, aktivuje háky nízké úrovně), ale přejde do libovolného okna je popředí a je blokován uiPI při vkládání z procesu se zvýšenými oprávněními do cíle nižší integrity (AppContainer/AppX). Pokud send-input nahlásí selhání, cíl pravděpodobně zvýší úroveň nebo aplikaci AppX – použije post-messagenebo spustí rozhraní příkazového řádku na odpovídající úrovni integrity. Jako bezpečnostní ochrana ověří, send-input že cílové okno je ve skutečnosti v popředí bezprostředně před vložením a selže (foreground_not_target) místo zadání do nesprávného okna , pokud fokus nelze převést na něj – fokus nebo první kliknutí na okno. Na uzamčené nebo zabezpečené ploše se místo toho nezdaří no_interactive_desktop ( neexistuje žádné okno popředí, do něhož se vloží) – odemkněte relaci nebo použijte příkaz vzoru UIA (set-value, invoke).
  • Systémově vyhrazená komba (win+l, win+r, ctrl+shift+escctrl+alt+delalt+tabalt+f4, ctrl+esc, lone win/printscreen, ...) se při odesílání operačního systému chová spíše než jen na cíl. send-input odmítne je ve výchozím nastavení (chyby s invalid_arguments a neodesílají nic), protože jejich vložení na úrovni operačního systému má účinky mimo cílové okno (například win+l by se relace zamkla). Předat --allow-system-keys výslovný souhlas – to vám umožní řídit globální klávesovou zkratku, jako je PowerToys' win+shift+v nebo win+r (globální hák nízké úrovně sleduje vstupní stream celého operačního systému, takže vložený kombinovaný soubor aktivuje). Výjimky, které zůstanou zablokované, i když --allow-system-keys:win+l uzamkne pracovní staniciLockWorkStation(), která není obnovitelná z automatizace (přeruší CI a relace vzdálené plochy) a ctrl+alt+del jedná se o sas (Secure Attention Sequence), která Windows zahodí vstup bez ohledu na příznak – nikdy se neprojeví, takže dojde k chybám (invalid_argumentsukončení 1) místo nahlášení zavádějícího úspěchu. Ostatní komba (alt+f4, , ctrl+shift+esc, win+r...) jsou povoleny s vlajkou — volající pozor. Alternativně, pokud chcete doručovat systém kombinovaný do konkrétního okna použití --via post-message, což je okno s rozsahem okna a není ovlivněno (příspěvek win+l je neškodný, i když vystavený alt+f4 stále zavře cílové okno).

Události stisknutí kláves (KeyDown / TextChanged):

  • Pojmenované klíče a modifikační komba (down, enter, ctrl+shift+t, vk=0xNN) aktivují skutečné KeyDown (a KeyUp) na obou přenosech – jsou dodávány jako diskrétní WM_KEYDOWN/WM_KEYUP (nebo SendInput virtuální klíčové události).
  • Text typu literál (hello) se liší podle přenosu:
    • --via send-input mapuje každý znak na jeho virtuální klávesu (plus Shift) v aktivním rozložení klávesnice, takže cíl vidí pravý KeyDown s správnou virtuální klávesou následovanou operačním systémem složeným WM_CHAR (zvýšením TextChanged) – tj. jedním úplným stisknutím kláves na znak. Znaky, které nejsou dostupné v aktuálním rozložení (nebo potřebují ctrl/AltGr), se vrátí k paketu Unicode, aby přesný znak stále přistál. Použijtesend-input, když potřebujete věrnost stisknutí KeyDown kláves (např. řízení WinUI 3 / WPF (Windows Presentation Foundation)TextBox, jejíž obslužné rutiny jsou vypnutéKeyDown). Pro normálního testovacího hostitele WinUI 3 (bez zvýšených oprávnění) přineste jeho okno na popředí (winapp ui focus / klikněte na něj), protože send-input cílí na okno popředí.
    • --via post-message publikuje jeden WM_CHAR znak na znak ( nezapisujeWM_KEYDOWN/WM_KEYUP pro zadaný text – ty jsou vyhrazeny pro pojmenované klíče/komba), což nevyvolává znak na znak KeyDown. Automaticky se přeměří na podřízený ovládací prvek okna, takže klasické ovládací prvky Win32/WinForms WM_CHARřízené úpravy přidají text (vyvolávání TextChanged). Námitka: Aplikace WinUI 3 / UPW / XAML (primární cíl winappu) mají ovládací prvky bez oken , které ignorují publikování WM_CHAR/WM_KEYDOWN – takže ani literálový text ani pojmenované klíče (Enter, číslice, ...) se k nim nedostane, i když příkaz hlásí úspěch. Vygeneruje upozornění, když cíl vypadá jako XAML a stále ukončí hodnotu 0 (PostMessage je vyvolán a zapomene a nemůže potvrdit doručení). Slouží --via send-input k řízení aplikací WinUI 3 / UPW / WPF (Windows Presentation Foundation); rezerva post-message pro klasické ovládací prvky Win32 nebo v případě, že ho potřebujete pouze v rozsahu okna napříč úrovněmi integrity.

Výstup JSON (--json):hwnd Výsledkem je efektivní okno, do kterého se klíče doručily – pro --via post-message toto je vyřešený podřízený ovládací prvek zaměřené na příkaz, když se na něj příkaz vrátí (ne nutně okno nejvyšší úrovně-w/-a/-e), takže automatizace může potvrdit přesně to, kam vstup přistál. Pokud tento efektivní cíl vypadá jako hostitel XAML bez oken, zobrazí se také upozornění na doručení výše jako warnings[] záznam (stejný poradce zobrazený na konzole), takže ✅ ukončení 0 není omylem pro potvrzené doručení.

set-value

Nastavte hodnotu u upravitelného prvku programově (bez stisknutí kláves, bez popředí aplikace). Používá záložní řetězec:

  1. ValuePattern — TextBox, ComboBox, PasswordBox a většinu upravitelných ovládacích prvků.
  2. RangeValuePattern – číselné ovládací prvky (Slider, ProgressBar), když se hodnota parsuje jako číslo.
  3. LegacyIAccessible (IAccessible::put_accValue) – záložní ovládací prvky pro úpravy pouze pro TextPattern , které nezpřístupňují žádné hodnoty ValuePattern (např. pole s formátováním nebo Document psaním). Tím se zavře mezera pro čtení a zápis, kde get-value by takový ovládací prvek mohl číst, ale set-value nemohl.
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

Pokud žádný ze tří vzorů nemůže nastavit hodnotu, set-value selže s jasnou chybou odkazující na send-keys poslední možnost.

Ne každý bohatý editor podporuje programovou sadu. Funkce LegacyIAccessible funguje jenom na ovládacích prvcích, jejichž funkce přístupnosti implementuje IAccessible::put_accValue – nativní ovládací prvky pro úpravy s formátem Win32 a chromium/Elektron/WebView2 obvykle dělají. WinUI 3 RichEditBox a WPF (Windows Presentation Foundation) RichTextBox nepodporují nastavení programových hodnot – záměrně zpřístupňují obsah model UI Automation jen pro čtení (vzor textu, bez nastavené hodnoty), takže set-value na ně nepůjdou zapisovat. Pro ty použijte send-keys (která potřebuje odemknutou plochu na popředí).

get-value

Přečtěte si aktuální hodnotu z elementu. Používá inteligentní záložní řetězec: TextPattern (RichEditBox, Document) → ValuePattern (TextBox, Slider) → SelectionPattern (ComboBox, RadioButton, TabView) → Název (popisky).

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

Úspěšně přečtené prázdné textové pole vrátí "text": "", ne jeho popisek přístupnosti. Obsah pouze prázdných znaků se zachová ve formátu JSON. wait-for --value "" odpovídá prázdnému poli bez ohledu na to, jestli je nové nebo bylo po úpravách vymazáno. Pokud chcete místo toho přečíst popisek přístupnosti, použijte get-property --property Name.

focus

winapp ui focus txt-textbox-a4b1 -a notepad

Aktivuje okno vybraného ovládacího prvku v případě potřeby a pak se zaměřuje na ovládací prvek. Selektor je povinný; použijte -a <app> nebo -w <HWND> zvolte cíl. Úspěch znamená, že okno bylo popředí a vybraný ovládací prvek se potvrdil HasKeyboardFocus před vrácením příkazu. Příkaz umožňuje až 500 ms, aby ovládací prvek hlásil fokus; zastaví se, pokud cíl zmizí nebo ztratí popředí a nebude se pokoušet zaměřit zpět. Vlastněné dialogové okno před hlavním oknem nestačí: pokud je to váš cíl, vyberte ovládací prvek v dialogovém okně.

Tento příkaz potřebuje odemknutou interaktivní plochu a nevyhne se Windows omezení aktivace. Pokud selže, foreground_not_targetaktivujte požadované okno ručně a před opakováním zkontrolujte dialogové okno blokování. Zkontrolujte focus_not_acquiredaktuální uživatelské rozhraní a zvolte ovládací prvek, který se dá zaměřit. V stale_elementpřípadě opětovné konfigurace cíle s inspect nebo search. Udržujte stejný --on cíl při zjišťování a opakování příkazů.

scroll-into-view

Posuňte prvek do viditelné oblasti.

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

čekání

Počkejte, až se prvek zobrazí, zmizí nebo bude mít hodnotu, která dosáhne cíle.

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

Posunout

Posuňte prvek kontejneru. Vyhledejte posuvné kontejnery search scroll – hledejte [scroll:v] (svislé) nebo [scroll:h] (vodorovné) značky.

# 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

Možnosti:

  • --direction <up|down|left|right> — Posouvání postupně přes ScrollPattern.
  • --to <top|bottom>— Přeskočte na začátek/konec .ScrollPattern
  • --wheel <notches> — Syntetizovat vstup kolečka myši přes střed prvku přes SendInput, v kolových závorkách (detenty): 1 = jeden zářez nahoru/pryč, -1 = jeden zářez dolů/směrem, 3 = tři zářezy nahoru. (Každý zářez je Windows WHEEL_DELTA 120 jednotek, které SendInput spotřebovávají; rozhraní příkazového řádku se škáluje o 120.) Obchází ScrollPattern.

--direction, --toa --wheel vzájemně se vylučují – předejte přesně jeden. Vzhledem k tomu --wheel , že vloží vstup v celém operačním systému na souřadnicích obrazovky, nejprve se cíl přesune na popředí a selže (foreground_not_target), pokud fokus nemohl být přenesen, a ne posouvání nesprávného okna.

get-focused

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

Umožňuje zobrazit prvek, který má aktuálně fokus klávesnice ve vybrané aplikaci, včetně ovládacích prvků, jejichž vlastnictví aplikace je dostupné pouze prostřednictvím nadřazeného okna. V -wpřípadě, že fokus musí patřit do daného okna, ne do jiného okna nebo vlastní automaticky otevírané okno ve stejném procesu. S -a, ostatní okna ve vybraném procesu jsou zahrnuta. Výstup JSON má hasFocus:false , když není možné ověřit žádný prioritní prvek, který patří do cíle. Pokud se fokus nebo dotaz na vlastnictví okna nezdaří, příkaz místo toho ukončí nenulový; opakujte get-focusedakci a znovu otevřete okno, list-windows pokud je zavřené.

list-windows

Zobrazí seznam všech viditelných oken pro aplikaci, včetně automaticky otevíraných oken a dialogových oken. Ve výchozím nastavení jsou bez názvu okna s nulovou velikostí (neviditelná systémová okna) vyloučena.

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

pozastavit

Uvolněte uživatelské rozhraní tohoto pracovního postupu brzy místo čekání na čtyřsekundovou nečinnou grace. Vyžaduje WINAPP_UI_WORKFLOW_ID– nevyžaduje žádnou aplikaci a žádný selektor. Viz Vydání turnu brzy.

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

Podpora architektury

.NET Framework Zkontrolovat hledání volat set-value screenshot
WPF (Windows Presentation Foundation) ✅ Celý strom ✅ Všechny vlastnosti ✅ Všechny vzory ✅ ¹ ✅
Formuláře WinForms ✅ ✅ ✅ ✅ ✅
Win32 ✅ ✅ ✅ ✅ ✅
WinUI 3 ✅ ✅ ✅ ✅ ¹ ✅
Elektron ⚠️ Chromium strom ⚠️ Omezené ⚠️ Liší se ⚠️ Liší se ✅
Flutter ⚠️ Základní ⚠️ Základní ❌ Minimální ❌ ✅

¹ set-value funguje na všech ovládacích prvcích, které zveřejňují ValuePattern/RangeValuePattern, a ovládací prvky pro úpravy pouze TextPattern, jejichž funkce přístupnosti implementuje IAccessible::put_accValue (záložní verze LegacyIAccessible). WinUI 3 RichEditBox a WPF (Windows Presentation Foundation) RichTextBox jsou výjimky – zpřístupňují pouze vzor textu jen pro čtení (bez nastaveného vzoru hodnoty), takže je nelze nastavit programově. K jejich psaní použijte send-keys (vyžaduje se interaktivní plocha).

Použití modulu z vlastního kódu

Všechno winapp ui je k dispozici jako knihovna, takže můžete řídit stejnou automatizaci z testovacího nebo nástroje, aniž byste museli zaskočít do rozhraní příkazového řádku:

Balíček Co přidává
Microsoft.Windows.SDK.BuildTools.WinApp.UIAutomation Kontrola, selektory, interakce vzorů UIA, vkládání vstupu, snímky obrazovky
Microsoft.Windows.SDK.BuildTools.WinApp.UIAutomation.Recording Nahrávání videa do MP4 a svazků snímků
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);

Pro deterministické akce použijte přetížení:UiInvokeAction

var selected = await ui.FindSingleElementAsync(
    target, new UiSelector { Query = "Save" }, requireUnique: true, default);
if (selected is null) throw new InvalidOperationException("Save was not found.");
UiInvokeActionResult result = await ui.InvokeAsync(target, selected, UiInvokeAction.Invoke, default);

requireUnique: true odmítne nejednoznačný text místo výběru vyvolání shody. Přesné shody AutomationId mají přednost před názvy nebo podřetěžci AutomationId; Jedinečný název může stále vybrat ovládací prvek, jehož Id automatizace je sdíleno. U cíle s vymezeným oborem aplikace se tato kontrola vztahuje na všechna jeho okna nebo okna vlastněná aplikací. K omezení oboru výběru použijte -w <HWND> (nebo cíl explicitní knihovny oken).

Vrátí Pattern a PerformedAction má stejný význam jako výsledek akce rozhraní příkazového řádku. Předejte prvek vrácený kontrolou nebo výběrem a jeho modul runtime slug nebo jedinečný AutomationId beze změny. Explicitní akce odmítnou chybějící nebo nejednoznačné identity místo opětovné vazby podle názvu a typu ovládacího prvku.

Pro čtení s vymezeným oborem nastavte UiSelector.Root na jiný UiSelector, ControlType na název typu a ClassName na třídu zprostředkovatele literálu. Používají stejné predikáty dotazů jako rozhraní příkazového řádku. Podporuje se pouze jedna kořenová úroveň: selector.Root.Root musí být null. Před vyhledáním cílového okna vyvolá ArgumentException vnořený kořen. Místo vnoření kořenových selektorů použijte jedinečný kořenový identifikátor AutomationId nebo slug. UiControlTypes.GetId(name) řeší oficiální názvy typů a dva zdokumentované aliasy, které 0 vrací neplatný název. UiControlTypes.GetName(id) vrátí kanonický název nebo Unknown(id) pro nerozpoznané ID.

Při předávání obnoveného UiElement z JSON do GetTextAsync nebo GetPropertiesAsync, zachovat jeho Selector a WindowHandle. Selektor slug musí stále identifikovat původní prvek; pokud již neexistuje, vyvolá se tato čtení UiElementNotFoundException namísto výběru jiného prvku se stejným id automation nebo názvem. Znovu spusťte původní dotaz a aktualizujte výsledek. Vymezená čtení také šíří chyby z obecných getterů vlastností UIA a získaných vzorů UIA místo vrácení hodnoty null nebo dříve zachycené hodnoty.

Záznam je samostatný balíček, aby projekty, které pouze kontrolují a řídí uživatelské rozhraní, nepřetahují do SkiaSharpu. Balíček automatizace cílí na net10.0-windows oba a net10.0-windows10.0.19041.0; druhý přidá Windows Graphics Capture, což je to, co umožňuje screenshot zachytit odlehlé nebo složených GPU windows. Úplný kompromis mezi rozhraním API a cílovým rozhraním najdete v souboru README jednotlivých balíčků na NuGetu.

UiTarget.FromWindowHandleje vstupním bodem pro testovací architektury, které už vám předá okno , například MSTest.Windows.UIAutomation, jehož WindowTest.MainWindow uiA2 přemýšlíte s .MainWindow.Current.NativeWindowHandleAutomationElement

Troubleshooting

Error Příčina Solution
"Nenalezena žádná spuštěná aplikace" Neshoda názvů nebo spuštění aplikace Kontrola názvu procesu nebo použití PID
"Shoda s více okny" Nejednoznačná -a hodnota Použití -w <HWND> z uvedených možností
"má více oken" Proces má více oken. Slouží -w <HWND> k cílení na konkrétní.
"Selektor odpovídá N prvkům" Nejednoznačný starší selektor Použití slugů z inspect výstupu nebo připojení [0][1]ke starším selektorům
"Prvek mohl být změněn" Hodnota hash Slug neodpovídá aktuálnímu prvku Opětovné spuštění inspect nebo search získání čerstvých slugů
"nepodporuje žádný vzor vyvolání" Prvek nelze vyvolat. Použití inspect elementu k vyhledání vyvolání podřízeného objektu
"Nenašlo se žádné okno UIA" UiA nemůže zobrazit proces Použijte list-windows k nalezení HWND a pak -w
"Okno má nulovou velikost" Minimalizované okno Aplikace se automaticky obnoví.
Místní nabídka nebo rozevírací seznam, který není na snímku obrazovky Výchozí zachytávání je pro každé okno a neobsahuje nepovlastněné překryvy. Postupujte podle pracovního postupu překrytí snímku obrazovky a vyberte okno s -w <hwnd> --capture-screen
foreground_not_target od --capture-screen Windows odmítli aktivaci, takže snímek obrazovky by zaznamenal jakékoli okno, které je ve skutečnosti před sebou. Klikněte na cílové okno nebo zavřete okno krádeže fokusu a zkuste to znovu nebo vypusťte. --capture-screen
element_not_found během záznamu Selektor zadaný, ale žádný odpovídající prvek Opětovné spuštění inspect nebo search získání nového selektoru
WGC není během záznamu k dispozici Inicializační inicializační inicializační operace WGC selhala; bez tichého náhradního režimu Kontrola GPU/ovladače; použití --capture-screen k vyjádření souhlasu se zachycením obrazovky DC

Běžné vzory

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

Vyhledání textu a vyvolání jeho nadřazeného objektu

# 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

Zrušit nejednoznačnost duplicitních prvků

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

Snímek obrazovky s překryvnými překryvnými okny

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

Zjišťování, kliknutí a ověření

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

Interakce s dialogovým oknem Soubor

Dialogy otevření/uložení souborů jsou standardní Windows dialogy s podporou 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>

Slouží inspect -w <dialog-hwnd> --interactive ke zjištění skutečných slugů pro konkrétní dialogové okno.

Proč ; řetězení (ne &&)

Operátor PowerShellu && může ukotvit, když nativní rozhraní příkazového řádku zapisuje do stderru nebo používá řídicí sekvence ANSI. Používejte ; místo toho – spouští každý příkaz bezpodmínečně a vyhne se tomuto vzájemnému zablokování. To je také lepší pro pracovní postupy agenta: Obvykle chcete, aby se snímek obrazovky spustil i v případě, že vyvolání mělo nenulové ukončení.

Vzory testování CI

Pro orientační testy a ověřování uživatelského rozhraní použijte příkazy winapp ui v kanálech CI (GitHub Actions, Azure DevOps). wait-for s kontrolním výrazem --property a --value funguje jako kontrolní výraz – vrátí ukončovací kód 1 při vypršení časového limitu a automaticky selhává krok CI.

Spuštění a testování v GitHub Actions

steps:
  - name: Build
    run: dotnet build MyApp.csproj -c Debug -p:Platform=x64

  - name: Launch and test
    run: |
      $result = winapp run .\bin\x64\Debug\net8.0-windows10.0.26100.0\win-x64 --detach --json | ConvertFrom-Json
      $appPid = $result.ProcessId

      # Wait for window to initialize
      winapp ui wait-for "Main Window" -a $appPid --timeout 30000

      # Run tests — each wait-for exits non-zero on failure
      winapp ui invoke "Login" -a $appPid
      winapp ui wait-for "Dashboard" -a $appPid --timeout 10000
      winapp ui screenshot -a $appPid -o dashboard.png

Assert – stav elementu s wait-for

wait-for --value se dotazuje, dokud hodnota prvku neodpovídá očekávanému řetězci, a to pomocí stejného inteligentního náhradního objektu jako get-value (TextPattern → ValuePattern → SelectionPattern → Name). Vrátí ukončovací kód 0 při shody, ukončete kód 1 při vypršení časového limitu – což z něj dělá kontrolní výraz kompatibilní s CI. Slouží --property ke kontrole konkrétní vlastnosti UIA.

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

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

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

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

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

Assert s výstupem JSON

Použití --json s PowerShellem nebo jq pro složitější kontrolní výrazy:

Ukončovací kontrakt kódu pro search a wait-for v --json režimu: pokud žádný prvek neodpovídá (search) nebo vypršení časového limitu čekání (wait-for), příkaz zapíše plně parsovatelnou obálku výsledku do stdout ({ "matchCount": 0, ... } nebo { "found": false, "timedOut": true, ... }) a vrátí ukončovací kód 1. Stderr je v --json režimu prázdný (výstup protokolovacího modulu je potlačen). Větvení na obálce polí nebo na $LASTEXITCODE, v závislosti na tom, která je ergonomickější.

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

Obálky JSON jsou:

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

Typové prvky používají type a používají číselné xprvky , y, width, a height. Geometrie je ve fyzických pixelech obrazovky. 0,0,0,0je model UI Automation obdélník prázdného nebo bez zobrazení uživatelského rozhraní v této projekci; isOffscreen je oddělený, takže prvek mimo obrazovku může mít i nadále nenulové hranice.

Každá inspect --jsonwindows[] položka a status --json výsledek zahrnují windowDpi, scale (windowDpi / 96), dpiAwarenessa coordinateSpace: "physical-screen-pixels". Tyto popisy popisují kontext DPI cílového okna, nikoli nepodmíněný monitor DPI: Windows hlásí 96 pro nevědí okno, systém DPI pro okno s podporou systému a aktuální monitor DPI pro okno s podporou monitorování. Pokud nelze přečíst kontext HWND nebo DPI, příkaz se nezdaří místo tiše nahrazování hodnoty 96. Při status překladu procesu před tím, než má okno nejvyšší úrovně, je 0 a pole DPI jsou vynechána, hwnd dokud okno neexistuje. U celého inspectprocesu zůstane vybrané cílové okno rychle neúspěšné. Pokud po přečtení stromu zmizí pozdější automaticky otevírané okno, windows[] jeho položka přenese dpiError pole DPI a vynechá pole DPI, zatímco zbývající stromy oken se budou stále vracet.

Kompletní příklady jednotlivých obálek najdete v dovednostech odeslaných winapp-ui-automationreferences/ui-json-envelope.md zásilek.

Příklad úplného orientačního testu

# 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