Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Inspecteer en communiceer met het uitvoeren van Windows toepassingen vanaf de opdrachtregel. Wordt gebruikt door AI-agents en ontwikkelaars voor het testen van gebruikersinterfaces, foutopsporing en automatisering.
Overzicht
winapp ui biedt opdrachten voor het controleren en gebruiken van Windows app-API's.
Maakt gebruik van Windows UI Automation (UIA). Werkt met elke Windows-app: WPF, WinForms, Win32, Electron en WinUI 3.
De meeste opdrachten sturen de app via UIA-patronen (geen invoerinjectie). De uitzonderingen injecteren echte invoer: ui click/ui hover/ui draggebruik muissimulatie,ui touch/ui pen synthetiseer aanraak- en pen-/stylusinvoer en ui send-keys synthetiseert toetsenbordinvoer voor besturingselementen en scenario's die UIA-patronen niet kunnen besturen.
Important
Interactieve bureaubladvereiste (invoerinjecterende werkwoorden).click, hover, , dragtouchpen, , scroll --wheelen send-keys --via send-input synthetiseer invoer op besturingssysteemniveau, zodat ze een ontgrendeld, interactief bureaublad nodig hebben met het doelvenster op de voorgrond. Op een vergrendeld werkstation of beveiligd bureaublad (LogonUI/UAC) kunnen ze niet snel injecteren en mislukken met no_interactive_desktop (los van de benodigde/foreground_not_target gevallen).
touch
/
pen weiger bovendien wanneer er geen venster wordt omgezet (no_target); een coördinaat buiten het doelvenster is een niet-fatale waarschuwing (een warnings[] vermelding onder --jsonof een waarschuwingsregel in de tekstmodus) en injectie gaat nog steeds verder , consistent met de muiswoorden. Al het andere : inspect, search, get-property, get-value, wait-for, , set-value, invoke- scroll --direction/--to stuurt de app door middel van UIA-patronen en is headless/locked-session vriendelijk.
screenshot is de uitzondering tussen de niet-injecterende werkwoorden: het neemt een exclusieve draai en de opname kan een bruikbaar interactief bureaublad nodig hebben, omdat de engine een geminimaliseerd doel herstelt en terugvalt op voorgrond wanneer frameopname niet beschikbaar is of --capture-screen wordt gebruikt. Geef de voorkeur aan de UIA-patroonwoorden in CI; reserveer de injectiewoorden voor scenario's die echt echte invoer nodig hebben. Voordat u het injecteert, lossen de gebaarwoorden ook het doelelement opnieuw op en weigeren ze met target_moved als het nog steeds animatie/verplaatsen is, in plaats van invoer te landen op lege ruimte.
Snel aan de slag
Uitvoeren winapp ui --help voor de kernlus: inspect -a <app> --interactive om te zien waar u actie op kunt ondernemen of invokeset-value om te handelen en get-value om het resultaat te controleren. Elke opdracht --help bevat voorbeelden. Een onbekende opdracht, zoals winapp ui dump, wordt afgesloten met code 1 en stelt de dichtstbijzijnde opdrachten voor (als een JSON-fout met suggestions wanneer u doorgeeft --json).
# 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
Ui-automatisering uitvoeren in Windows Sandbox
Als u automatisering buiten uw bureaublad wilt houden, voegt u deze toe --on sandbox aan de opdrachten voor uitvoeren en gebruikersinterface:
winapp run . --on sandbox --detach
winapp ui inspect --on sandbox -a MyApp
winapp ui invoke --on sandbox SubmitButton -a MyApp
--detach retourneert na het starten; run wacht totdat de app is afgesloten. Houd --on sandbox elke gastopdracht bij, inclusief die met een PID of venstergreep.
Zie Windows Sandbox-uitvoering voor clientvereisten, korte wijzigingen in de focus instellen/opnieuw verbinden, werkstroomcoördinatie en levering van hostuitvoer.
Scoped en getypte query's
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
winapp ui invoke Open -w <dialog-HWND> --type Button
winapp ui set-value "Text editor" "hello" -a notepad --type Document
Deze opdrachten accepteren optionele filters voor de elementkiezer: inspect (met een selector), search, get-property, get-value, wait-for, , invoke, set-value, focusscrollclickhoverscroll-into-view, screenshot, recorden .pentouch
drag (twee selectors) en send-keys --target niet.
De selector en elk opgegeven filter moeten overeenkomen met hetzelfde element. Filters beperken een selector, dus inspectscreenshot, en record, waarvan de selector optioneel is, mislukken met invalid_arguments wanneer bepaalde filters zonder één.
penFilters touch hebben een selector nodig; ze kunnen niet worden gecombineerd met --at of --path (invalid_arguments):
-
--root <selector>zoekt alleen afstammelingen van één unieke overeenkomende hoofdmap, nooit de hoofdmap zelf. Gebruik een AutomationId of slug vaninspectom ondubbelzinnig te zijn. Een hoofdmap die overeenkomt met meerdere elementen mislukt,ambiguous_selectorzelfs als één overeenkomst kan worden aanroepbaar. Een ontbrekende hoofdmap produceert geen overeenkomsten. Zodra de hoofdmap is gevonden, zoeken query's niet in niet-gerelateerde pop-upvensters, zelfs niet als er geen onderliggende vensters overeenkomen. Query's worden niet beperkt doorinspectde weergavediepte. -
--type <control-type>komt overeen met een UIA-besturingselementtype, waarbij hoofdletters en kleine letters worden genegeerd. De enige aliassen zijnTextBox→EditenTextBlock→Text. Onbekende namen (inclusief numerieke id's en jokertekenexpressies) mislukken metinvalid_arguments. -
--class-name <literal>komt overeen met de volledige UIAClassNamevan de provider, waarbij case wordt genegeerd. Het is geen subtekenreeks, jokerteken of reguliere expressie. Gebruikget-property --property ClassNamedit om de waarde van de provider te detecteren. De klassenaam hoeft niet gelijk te zijn aan het type UIA-besturingselement.
Gefilterde query's maken gebruik van de besturingselementweergave van UIA, dezelfde weergave die wordt weergegeven door inspect.
Providerknooppunten die alleen beschikbaar zijn in de Onbewerkte weergave, worden niet geretourneerd; gebruikt inspect om het besturingselement en de bijbehorende selector te zoeken.
Alle 41 officiële typen worden ondersteund: Button, Calendar, CheckBox, ComboBox, ToolBarTabItemTabTextToolTipTreeStatusBarHyperlinkProgressBarListImageMenuItemMenuBarListItemEditRadioButtonSliderMenuSpinnerTreeItemScrollBar, , AppBarTitleBarSemanticZoomSeparatorHeaderItemTableCustomGroupThumbDataGridDataItemDocumentSplitButtonWindowPaneHeader
wait-for lost de hoofdselector opnieuw op bij elke poll, zodat de hoofdmap kan worden weergegeven nadat de opdracht is gestart. Met --gone, een afwezige wortel betekent dat er geen overeenkomende afstammeling is; een dubbelzinnige hoofdmap is een fout, niet geslaagd.
Een onderbroken zoekactie is geen bewijs van verdwijning: als een element wordt verwijderd tijdens het opzoeken of vervangen voordat een --value leesbewerking plaatsvindt, wordt de volgende poll opnieuw gecontroleerd; andere zoek- of leesfouten mislukken de opdracht.
-w <HWND> beperkt de hoofddetectie tot de UIA-structuur van dat venster. Met -ade hoofddetectie kunt u ook de pop-upvensters van de app vinden. Exact root AutomationId-overeenkomsten hebben voorrang op subtekenreeksovereenkomsten in al die vensters; meerdere exacte overeenkomsten mislukken nog steeds met ambiguous_selector.
Een hoofdslak selecteert dat element zelfs wanneer een ander venster dezelfde AutomationId heeft. Als de geselecteerde wortel wordt vervangen, komt de oude slak niet meer overeen; gebruik een AutomationId of naamhoofdmap wanneer u een polling wilt volgen op een vervanging.
Wanneer er filters aanwezig zijn, mislukt elke opdracht, behalve search mislukt met ambiguous_selector als er meer dan één element overblijft; verfijn de filters of gebruik een unieke slug. Opdrachten die reageren op het aantal elementen in elk venster waarnaar ze zoeken, zodat een overeenkomend besturingselement in een dialoogvenster in eigendom ook de selector dubbelzinnig maakt. Exacte AutomationId-overeenkomsten behouden prioriteit boven subtekenreeksovereenkomsten, binnen het gefilterde bereik. Als u alle drie de opties weglaat, blijft het bestaande querygedrag behouden.
Gelijktijdige UI-werkstromen coördineren
Windows heeft slechts één voorgrondvenster, één toetsenbordfocus, één cursor en één invoerstroom. Wanneer twee winapp ui werkstromen tegelijk op hetzelfde aangemelde bureaublad worden uitgevoerd, kunnen ze de focus van elkaar stelen, een menu sluiten dat de andere zojuist is geopend of een doel verplaatsen van onder een klik in behandeling.
Arbitrage is altijd ingeschakeld. Elke winapp ui opdracht die het fysieke bureaublad raakt, neemt een beurt, zonder installatie en geen manier om deze uit te schakelen, zodat twee agents nooit in elkaars vensters kunnen typen. Opdrachten met het kenmerk Alleen-lezen blijven gelijktijdig worden uitgevoerd. De enige uitzondering is een proces dat geen toegang heeft tot de coördinatiemap van Winapp, zoals een agent-sandbox die blokkeert %USERPROFILE%\.winapp: de opdrachten worden nog steeds uitgevoerd, maar zonder beurten, en een waarschuwing afdrukken (behalve met --json of --quiet).
Continuïteit tussen opdrachten is opt-in. Standaard is elke opdracht een zelfstandig één shot: het wacht zijn beurt, doet het werk en brengt het bureaublad onmiddellijk vrij. Als u het bureaublad over verschillende opdrachten wilt houden, geeft u ze allemaal dezelfde werkstroom-id:
# Set once per logical UI workflow
$env:WINAPP_UI_WORKFLOW_ID = [guid]::NewGuid().ToString()
Wat u moet weten:
- Een werkstroom-id noemt één logische werkstroom , niet noodzakelijkerwijs een hele agent en niet noodzakelijkerwijs één app. Gebruik dezelfde waarde voor medewerkende opdrachten (een opname plus de klikken die erop moeten worden vastgelegd); gebruik verschillende waarden voor onafhankelijke werkstromen, zelfs wanneer één agent beide wordt gestart.
- Zonder id is elke opdracht een onafhankelijke één shot. Het scheidt nog steeds, maar het banken geen genade en geeft het bureaublad af op het moment dat het klaar is. Twee no-id opdrachten zijn afzonderlijke werkstromen, zelfs wanneer ze vanuit dezelfde shell worden gestart.
- Fresh-shell en adaptieve hosts moeten dezelfde waarde invoeren. Als elke opdracht wordt uitgevoerd in een nieuwe shell, zoals de meeste agenthulpprogramma-aanroepen werken, is het enige dat ze kan groeperen, een expliciete
WINAPP_UI_WORKFLOW_IDdoorgegeven aan elke medewerkende aanroep. - De vier seconden respijt beschermt strakke bursts, geen modelredenering. Een werkstroom met een id houdt de beurt zolang de volgende opdracht binnen vier seconden begint. Dat omvat back-to-back-opdrachten in één script; het opzettelijk verloopt terwijl een model denkt. Het is een terugval voor wanneer u niet kunt zeggen dat u klaar bent, wanneer u kunt, uitvoeren
winapp ui yieldin plaats van te wachten. - Adaptieve werkstromen moeten opnieuw worden gevraagd, opnieuw worden gevalideerd en opnieuw worden afgespeeld. Nadat een redeneringsverschil in een andere werkstroom mogelijk het bureaublad heeft gebruikt, opent u het menu opnieuw, lost u het element opnieuw op en handelt u vervolgens. Stuur bekende end-to-end-reeksen als één strak script in plaats van het bureaublad vast te houden terwijl u denkt.
- Bestellen is eerst eigenaaraffiniteit en vervolgens FIFO onder andere. Hoewel een werkstroom actief is of binnen de respijtperiode valt, kan het blijven werken met opdrachten, zelfs als andere werkstromen al wachten. Zodra het wordt uitgevoerd
winapp ui yieldof de respijt verloopt, worden wachtende werkstromen geleverd in strikte aankomstvolgorde. Continue activiteit door één werkstroom kan daarom voor onbepaalde tijd andere activiteiten vertragen. - Er is geen harde dop. Een lang script, een niet-gebonden opname of een foutlus kan andere mutatiewerkstromen blokkeren.
-
Annulering of procesbeëindiging is het herstel voor een vastgelopen livewerkstroom. Wachtende opdrachten drukken na één seconde een status af en kunnen worden gestopt met
Ctrl+C, die wordt afgesloten130. - Alleen compatibele bijgewerkte binaire bestanden werken samen. Oudere
winappbuilds zijn vóór deze functie en worden niet gecoördineerd. Code die de UI Automation NuGet-pakketten rechtstreeks aanroept, valt volledig buiten deze garantie: coördinatie bevindt zich in de CLI, niet in de pakketten.
Welke opdrachten wachten op een beurt:
| Behavior | Commands |
|---|---|
| Wordt gelijktijdig uitgevoerd (wacht nooit) |
status, list-windows, inspect, search, get-property, get-value, , get-focused, wait-for |
| Wacht op de beurt, maar neemt nooit het bureaublad |
set-value, , , scroll-into-viewscroll --direction/--torecord |
| Wacht op de beurt en neemt het bureaublad exclusief |
invoke, , drag, hoverclick, , scroll --wheel, touch, , send-keysfocuspenscreenshot |
De middelste rij is de enige die het waard is om te begrijpen.
set-value
--to
scroll --direction
/en scroll-into-view rij UIA-patronen in plaats van de voorgrond, zodat ze headless/vergrendelde sessie vriendelijk blijven en nooit voorkomen dat iemand het bureaublad gebruikt. Maar ze veranderen wel wat de app weergeeft, dus wachten ze achter de beurt van een andere werkstroom in plaats van een veld te bewerken of door een lijst onder de klik van iemand anders te schuiven.
Binnen de ene werkstroom overlappen ze met ander gedeeld werk, zoals een record opname van de set-value aanroepen ervan vastlegt. Ze negeren de voorwaartse barrière van hun eigen werkstroom niet: een eerdere DesktopExclusive opdracht van dezelfde werkstroom (a , a clickscreenshot) blokkeert ze nog steeds, precies zoals het elke latere opdracht blokkeert, dus een klik en de mutatie die erop volgt, blijft in de volgorde waarin u ze schreef.
screenshot altijd wachtrijen voor een exclusieve beurt. Niet elke opname storen het bureaublad - een gewoon zichtbaar venster dat is vastgelegd via Windows Graphics Capture niet - maar de engine herstelt het doel als het wordt geminimaliseerd en valt terug op de voorgrond wanneer frameopname niet beschikbaar is of --capture-screen het live scherm leest. Die hebben slechts surface nodig zodra het vastleggen is voltooid, dus de opdracht neemt de voorgrond in plaats van te raden. Wanneer het meerdere vensters samenstelt, worden ze allemaal vastgelegd onder één exclusieve draai, zodat de opgeslagen afbeelding één consistent moment is in plaats van een combinatie van voor en na. Het coderen en schrijven van het bestand vindt plaats nadat het bureaublad is vrijgegeven.
--capture-screenheeft precies één venster nodig. Live-schermopname registreert alles wat er daadwerkelijk voor staat en slechts één venster kan zijn. Als u een venster expliciet selecteert,-w <hwnd>krijgt het precies één gebied: de pixels binnen de grenzen van dat venster, inclusief dialoogvensters of overlays die zichtbaar zijn op het scherm, wat de reden is om het scherm op de eerste plaats te lezen. Wanneer-adeze overeenkomsten overeenkomen met verschillende vensters op het hoogste niveau of in eigendom, is er geen dergelijke selectie, dus de opdracht mislukt voordatinvalid_argumentsu iets vastlegt in plaats van de voorgrond te bestrijden. Voerwinapp ui list-windows -a <app>het uit en probeer het opnieuw met-w <hwnd>, of zet het--capture-screenneer op samengesteld elk venster vanuit een eigen inhoud.
record deelt zijn beurt, zodat invoer van dezelfde werkstroom kan worden opgeslagen met de opname, zoals u een werkstroom registreert die een app aansturen. Twee opmerkingen:
- Een
recordzonder werkstroom-id is een eigenaar van één opname, zodat elke andere werkstroom gedurende de hele duur wordt geblokkeerd. Als u op hetzelfde moment wilt opnemen en erop wilt klikken, geeft u beide opdrachten dezelfdeWINAPP_UI_WORKFLOW_ID. - Op een host zonder frame-capture-ondersteuning valt de opname terug naar PrintWindow, waarvan het herstel van het lege frame het venster op elk moment op de voorgrond kan plaatsen. Daar wordt het bureaublad bewaard voor de volledige opname en de opdracht zegt dit in de uitvoer; zelfs invoer van dezelfde werkstroom wacht.
Fouten die u kunt zien: invalid_ui_workflow_id (de variabele is ingesteld maar leeg of meer dan 256 tekens), desktop_coordination_unavailable (coördinatiestatus is onleesbaar en kan niet veilig opnieuw worden opgebouwd, of is geschreven door een nieuwer winapp), queue_capacity_exceeded (64 opdrachten van andere werkstromen wachten al: de limieten tellen live buitenlandse obers, niet processen die u hebt gestart, dus vermeldingen die behoren tot opdrachten die zijn afgesloten of zijn gedood, bezetten geen site, en de opdrachtenwachtrij van uw eigen werkstroom achter elkaar in plaats van tegen deze limiet), ui_turn_busy (yield terwijl uw eigen werkstroom nog steeds een opdracht heeft die wordt uitgevoerd) en cancelled (Ctrl+C tijdens het wachten, afsluitcode 130).
De beurt vroeg vrijgeven: winapp ui yield
De vier seconden respijt is een terugval: het houdt het bureaublad gereserveerd wanneer u niet zeker weet dat u klaar bent. Als u dit kunt zeggen, geeft u yield het bureaublad onmiddellijk over in plaats van dat iedereen een genade laat wachten die niemand nodig heeft.
$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
- Eenmalige opdrachten mogen helemaal geen werkstroom-id instellen. Zonder één opdracht wordt het bureaublad al vrijgegeven op het moment dat deze is voltooid en er is niets om op te leveren.
- Werkstromen met meerdere stappen moeten opleveren wanneer ze zijn voltooid, met name wanneer andere werkstromen mogelijk wachten. Het kost één snelle opdracht en verwijdert een stalletje van vier seconden van iedereen.
- Het is idempotent. Twee keer opleveren, of nadat de respijt al is verstreken, slaagt en rapporteert
{ "released": false }, dat is het normale einde van een script, niet een fout. - Er wordt nooit een andere werkstroom uitgebracht. Als iemand anders het bureaublad heeft of niemand dat doet, is het een no-op.
- Het mislukt met
ui_turn_busyals uw eigen werkstroom nog steeds een opdracht heeft die wordt uitgevoerd of in de wachtrij staat, bijvoorbeeld een opname. Als u het bureaublad halverwege de opdracht vrijgeeft, wordt er dus niets vrijgegeven en wordt de actieve opdracht niet beïnvloed. Wacht erop of stop het en geef het weer op. - Het vereist
WINAPP_UI_WORKFLOW_ID. Zonder één mislukt het metinvalid_arguments. - Het duurt geen app en geen selector: het geeft een reservering terug, geen venster, dus het werkt nog steeds nadat de app is gesloten.
Een wachtopdracht wordt wakker door degene die het bureaublad vrijgeeft in plaats van door ernaar te peilen, dus een wachtrij kost bijna niets terwijl het wacht en de overdracht onmiddellijk is. Elke ober controleert ook af en toe opnieuw, wat het bureaublad herstelt wanneer een proces wordt gedood en nooit iets publiceert: de opdracht aan het hoofd van de wachtrij ziet er elke halve seconde uit en opdrachten achter het hoofd van de wachtrij, die niet kunnen worden uitgevoerd voordat het hoofd toch wordt uitgevoerd, elke paar seconden.
Apps instellen
Op procesnaam
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
winapp ui search Seven -a calculator # hosted app: uses the frame window that hosts it
Sommige verpakte apps (bijvoorbeeld Calculator) hebben geen eigen venster; een ander proces fungeert als host voor hun frame. Wanneer het overeenkomende proces (op naam of PID) geen zichtbaar venster heeft, -a gebruikt u in plaats daarvan het frame dat als host fungeert voor de inhoud. Als er geen is (bijvoorbeeld als de app nog steeds wordt gestart), -a is het proces gericht, dus wait-for blijft kijken totdat het venster wordt weergegeven.
Op venstertitel
winapp ui inspect -a "LICENSE - Notepad"
winapp ui inspect -a "Fix WinApp" # partial title match
Per PID
winapp ui inspect -a 12345
Door HWND (stabiel — overleeft tab-/titelwijzigingen)
# 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
Gebruiken -a voor detectie, -w voor stabiele targeting. Wanneer -a deze overeenkomen met meerdere vensters, worden deze weergegeven met HWND's die u kunt kiezen.
Selectoren
Doelelementen met behulp van de selector die wordt weergegeven in [brackets] inspect/search-uitvoer.
Er zijn drie typen selectors:
| Selector | Meaning | Example |
|---|---|---|
MinimizeButton |
AutomationId (weergegeven als uniek — stabiel, voorkeur) | winapp ui invoke MinimizeButton -a myapp |
btn-close-d1a0 |
Semantische slug (weergegeven wanneer geen unieke AutomationId) | winapp ui invoke btn-close-d1a0 -a myapp |
Submit |
Zoeken in tekst zonder opmaak op naam/AutomationId (hoofdlettergevoelige subtekenreeks) | winapp ui invoke Submit -a myapp |
AutomationId-selectors zijn id's voor ontwikkelaarssets (AutomationProperties.AutomationId in XAML).
Wanneer een AutomationId uniek is in de hele UI-structuur inspect en search deze rechtstreeks als de selector weergeeft, blijven de indelingswijzigingen, lokalisatie en structuurherstructurering behouden.
Slugselectors (bijvoorbeeld btn-close-d1a0) worden gegenereerd wanneer er geen unieke AutomationId bestaat.
Indeling: prefix-name-hash. De hash valideert de elementidentiteit, maar kan verlopen nadat de gebruikersinterface is gewijzigd.
Uitvoerindeling controleren
De inspect opdracht toont de elementstructuur met gekleurde uitvoer (selector in cyaan, naam in groen, metagegevens in grijs):
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
Het eerste woord op elke regel is de selector. Gebruik het met andere ui opdrachten.
Wanneer een element een unieke AutomationId heeft, wordt het rechtstreeks gebruikt (bijvoorbeeld TabView, NewTabButton).
Wanneer er geen unieke AutomationId bestaat, wordt er een gegenereerde slug gebruikt (bijvoorbeeld tab-newtab-5f5b).
Semantische slugs
Slugs gebruiken de notatie: prefix-normalizedname-hash waarbij:
- voorvoegsel — afkorting van 3 letters (btn, txt, chk, cmb, itm, tab, img, lbl, pn, win, grp, lnk, mnu, enz.)
- normalizedname : alfanumerieke kleine letters van AutomationId (voorkeur) of Naam, maximaal 15 tekens
- hash : hexhash van 4 tekens van de RuntimeId van het element (valideert elementidentiteit)
Slugs zijn shell-safe (geen speciale tekens), uniek en kunnen rechtstreeks als argumenten worden gebruikt. Zonder queryfilters biedt de hash verouderingsdetectie. Als het element is vervangen, krijgt u het volgende: 'Element is mogelijk gewijzigd. Voer de inspectie opnieuw uit." Zie Bereik- en getypte query's voor gefilterde query's.
Elementen zonder naam of AutomationId geven alleen voorvoegsel en hash weer (bijvoorbeeld pn-c8a3).
Meerdere overeenkomsten ondubbelzinnig maken
Slugs van inspect/search uitvoer zijn uniek, maar kunnen worden gewijzigd in indelingswijzigingen. Gebruik ze boven namen of tekst zonder opmaak wanneer meerdere overeenkomsten overeenkomen. Wanneer een selector dubbelzinnig is, worden alle overeenkomsten met hun slugs afgedrukt, zodat u de juiste kunt kiezen en opnieuw kunt uitvoeren met die slug.
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
Zoeken in tekst zonder opmaak
Gebruik tekst zonder opmaak om te zoeken naar elementen. Er is geen speciale syntaxis nodig:
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
Wanneer een tekstzoekopdracht overeenkomt met meerdere elementen (bijvoorbeeld SettingsExpander waarbij groep, knop en tekst allemaal dezelfde naam delen), kiest de CLI automatisch het enige aanroepbare element. Als er meerdere aanroepbaar zijn, worden alle overeenkomsten met slugs weergegeven.
Voor niet-aanroepbare zoekresultaten (bijvoorbeeld een TextBlock binnen een knop), wordt automatisch de dichtstbijzijnde aanroepbare bovenliggende bovenliggende waarde weergegeven, het bovenliggende element waarmee invokeu kunt gebruiken.
Dit werkt voor alle zoekkiezers:
lbl-savechanges-a1b2 "Save changes" (120,40 80x20)
^ invoke via: btn-save-c3d4 "Save"
De surfaced selector kan rechtstreeks worden gebruikt:
winapp ui invoke btn-save-c3d4 -a myapp # invoke the parent Button
Commands
status
Maak verbinding met een app en geef verbindingsgegevens weer.
winapp ui status -a notepad
winapp ui status -a notepad --json
Inspecteren
Bekijk de structuur van het ui-element. De uitvoer toont semantische slugs met twee spaties inspringing voor de hiërarchie:
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 # elements you can invoke, click, or set-value; auto-depth 8
winapp ui inspect -a myapp --hide-disabled # hide disabled elements
winapp ui inspect -a myapp --hide-offscreen # hide offscreen elements
Voorbeelduitvoer (standaard):
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)
Voorbeelduitvoer (--interactive — alleen bruikbare elementen, platte lijst):
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)
Elementen kunnen deze statusmarkeringen weergeven:
-
[on]/[off]/[indeterminate]— status van wisselknop/selectievakje -
[collapsed]/[expanded]— de status voor bomen, keuzelijsten met invoervak, menu-items uitvouwen/samenvouwen -
[scroll:v]/[scroll:h]/[scroll:vh]— schuifbare container (verticaal, horizontaal of beide) -
[offscreen]— element is niet zichtbaar op het scherm -
[disabled]— element is niet ingeschakeld -
value="..."— huidige tekstinhoud voor bewerkbare elementen (indien anders dan Naam)
search
Zoek elementen die overeenkomen met een selector. Uitvoer toont semantische slugs:
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
Voorbeelduitvoer:
btn-minimize-d1a0 "Minimize" (1222,206 48x48)
btn-maximize-e2b1 "Maximize" (1270,206 48x48)
btn-close-d1a2 "Close" (1318,206 48x48)
Slugs die worden weergegeven in de uitvoer (bijvoorbeeld btn-minimize-d1a0) kunnen rechtstreeks worden gebruikt met andere opdrachten:
winapp ui invoke btn-minimize-d1a0 -a notepad
get-property
Eigenschapswaarden van een element lezen. Bevat patroonspecifieke status (ToggleState, Waarde, IsSelected, enzovoort).
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
Eigenschapsnamen zijn hoofdlettergevoelig. Een onbekende naam mislukt met invalid_arguments onder --json; laat de --property eigenschappen weg, inclusief alle zes de onderstaande kenmerken voor tekstopmaak.
wait-for --property gebruikt dezelfde hoofdlettergevoelige namen en weigert onbekende namen voordat er wordt gepeild.
Tekstopmaak voor hele documenten
Opmaak wordt gelezen in het hele TextPattern-document van het element, niet de huidige selectie of caret. Leesbewerkingen wijzigen de focus of selectie niet.
| Property | Uniforme waarde (geretourneerd als een tekenreeks) |
|---|---|
FontWeight |
Numeriek gewicht, zoals "400" (normaal) of "700" (vet) |
FontName |
Naam van lettertypefamilie, zoals "Courier New" |
FontSize |
Grootte in punten, zoals "15.5" |
ForegroundColor |
Decimale Windows COLORREF (0x00BBGGRR), zoals "3678732" voor RGB(12, 34, 56) |
IsItalic |
"True" of "False" |
StrikethroughStyle |
Numerieke UIA-stijl voor tekstdecoratie, zoals "0" (geen) of "1" (enkel) |
Getallen gebruiken invariante opmaak (een decimaalteken, ongeacht uw landinstelling). Elk kenmerk kan in plaats daarvan het volgende retourneren:
| Value | Betekenis en volgende stap |
|---|---|
"Mixed" |
De opmaak varieert binnen het document. Behandel het niet als een uniforme waarde; met deze opdracht wordt geen query uitgevoerd op afzonderlijke tekstbereiken. |
"NotSupported" |
De TextPattern-provider van het document rapporteert dit kenmerk niet. Controleer de toegankelijkheidsondersteuning van de app. |
"Unavailable" |
Het element heeft geen TextPattern. Gebruik inspect of search zoek het bijbehorende tekst-/documentelement. |
Wanneer u alle eigenschappen weergeeft, blijven de basiseigenschappen in de cache beschikbaar als er geen live-element kan worden opgelost en wordt een ongeldige opmaakwaarde weggelaten zonder andere eigenschappen te verwijderen. Deze weglatingen worden vastgelegd als waarschuwingen. Vraag een specifieke opmaakeigenschap aan om een fout op te halen in plaats van een omissie.
Providerfouten blijven fouten, niet "Unavailable". Inspecteer stale_elementde app opnieuw en probeer het opnieuw met een huidige selector.
De JSON-envelop bevat elementId, een getypte elementen tekenreekswaarde properties.
Bestaande eigenschappen, waaronder BoundingRectangle, behouden hun indelingen.
Het opmaakgedeelte is properties bijvoorbeeld:
{
"FontWeight": "700"
}
schermopname
Een venster of element vastleggen als 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)
Zonder een elementkiezer combineert standaardopname meerdere vensters in één gelabelde, side-by-side samengestelde PNG, niet afzonderlijke bestanden.
-a op procesnaam of PID omvat de vensters van de app en de bijbehorende vensters. Een overeenkomst op basis van -a een titel selecteert één overeenkomend venster plus de bijbehorende vensters. -w Selecteer expliciet één venster plus de bijbehorende vensters, niet elk venster in het proces. Een dialoogvenster of knopinfo in eigendom kan daarom worden weergegeven als een eigen paneel, zelfs wanneer u expliciet de hoofd-HWND selecteert. Een elementselector snijdt in dat element bij in plaats van vensters op te stellen. Een element in een menu, flyout, knopinfo of lestip die in een eigen pop-upvenster wordt geopend, wordt bijgesneden vanuit dat pop-upvenster, niet vanuit het venster daarachter.
--quiet onderdrukt informatieve uitvoer voor zowel enkelvoudige als samengestelde opnamen, inclusief het opgeslagen pad. Waarschuwingen en diagnostische gegevens over capture-failure blijven zichtbaar. Gebruik --json in plaats daarvan wanneer u het bestandspad en de dimensies nodig hebt als gestructureerde uitvoer.
Met --on sandboxde naam van --output de hostbestemming. Geslaagde uitvoer zonder opmaak en --json rapporteer dat hostpad nadat de installatiekopie is geleverd.
Het standaardpad voor vastleggen maakt gebruik van Windows. Graphics.Capture (WGC), het lezen van het werkelijke DWM-samengestelde oppervlak, met behoud van afgeronde hoeken, transparantie en werken zelfs terwijl het venster wordt ondergesloten door andere windows. Als WGC niet beschikbaar is (oudere Windows builds) valt de CLI terug naar PrintWindow.
Gebruik --capture-screen -w <hwnd> deze functie wanneer u zichtbare pop-ups of knopinfo nodig hebt op hun schermposities, inclusief overlays die niet eigendom zijn van het doelvenster. Het leest het schermgebied van dat venster in plaats van gelabelde panelen op te stellen en brengt het venster eerst op de voorgrond. Met -a, het vereist exact één overeenkomend venster; als meerdere vensters op het hoogste niveau of eigendom overeenkomen, gebruiken winapp ui list-windows -a <app> en opnieuw proberen met -w <hwnd>. Gebruik --focus deze optie als u alleen het venster wilt voorgronden zonder over te schakelen tussen opnamemodi (bijvoorbeeld om ervoor te zorgen dat de schermopname overeenkomt met wat de gebruiker momenteel bekijkt).
Omdat de schermdomeincontroller legt wat er daadwerkelijk voor staat,
--capture-screencontroleert u of het doel de voorgrond onmiddellijk heeft bereikt voordat het wordt vastgelegd en misluktforeground_not_targetals dit niet heted (focus-steeling preventie, een UAC-prompt of een ander venster dat zichzelf activeert). In dat geval is er geen afbeelding geschreven, eerder werd de opdracht 0 afgesloten en een afbeelding van het verkeerde venster teruggestuurd.ui record --capture-screenpast dezelfde controle toe vóór het eerste frame.
verslag / opname
Noteer een venster of elementgebied naar een H.264 MP4. Geef de voorkeur aan een positief voor --duration-sec scripts zonder toezicht. Zonder duur gaat de opname door tot Ctrl+C of, voor omgeleide stdin, een nieuwe regel of EOF. De npm uiRecord en targetRecord helpers vereisen een geheel getal durationSec van 1 tot en met 86400; hun afgebroken signaal annuleert geforceerd in plaats van een opname correct af te ronden.
# 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
Opties:
-
--duration-sec N— Record voor N seconden. Standaard 0 records totdat deze is gestopt. -
--fps N— Doelframes per seconde (standaard 15). -
--max-edge N— Omlaag schalen zodat de langste rand maximaal N pixels is (0 = geen downscale). -
--capture-screen— Vastleggen vanaf het scherm DC (inclusief overlays/pop-ups; voorgrond van het venster). -
--output <path>— MP4-uitvoerpad. Wordt standaard ingesteld oprecording-<timestamp>-<guid>.mp4. -
--overwrite— Vervang bestaande opname-uitvoer nadat de nieuwe uitvoering is voltooid. Zonder deze worden bestaande uitvoer geweigerd. -
--frames— Tijdstempel van JPEG-bewijs schrijven naar<output-name>.frames. Ondersteunt 1-30 fps en--max-edge64-4096 (standaard 1280). Framegegevens worden beperkt tot 1 GiB; de MP4 wordt voortgezet als de limiet is bereikt.
Door agents leesbare frameartefacten:
evidence.mp4
evidence.frames/
manifest.json
frames.ndjson
frames/
frame-000000-t000000000012.jpg
frames.ndjson heeft één regel per steekproef met sampleIndex, monotone elapsedMs, MP4-relatieve mediaTimeMs, imageIndex, fileen changed. Opeenvolgende pixel-identieke steekproeven hergebruiken de voorgaande kwaliteit-85 JPEG.
manifest.json registreert de aanvraag, timing, MP4-status, afbeeldingsdimensies en status (complete, partialof truncated). Afgekapte tijdsinstellingen hebben betrekking op het behouden voorvoegsel, terwijl video de volledige MP4 wordt beschreven.
Kies een nieuw uitvoerpad, tenzij u een opname wilt vervangen door --overwrite.
Zonder deze, een bestaande video of de gekoppelde .frames map blokkeert opname, zelfs wanneer u weglaat --frames.
De vorige MP4 blijft intact als de nieuwe opname mislukt. Bij een geslaagde vervanging blijft de vorige framemap behouden als <output-name>.frames.previous-<id>, zelfs als de nieuwe opname weglaat --frames. Bewaar gedeeltelijk bewijs en volg de gerapporteerde recoveryHint gegevens voordat u het opnieuw probeert. Als de MP4-voltooien mislukt, kunnen bewaarde frames worden gepubliceerd onder <output-name>.frames.partial-*. Frameartefacten bevatten niet-versleutelde scherminhoud; afhandelen ze, zoals schermopnamen of video's.
Met --on sandboxworden zowel de MP4- als de framemap aan de host geleverd, inclusief standaarduitvoer wanneer --output deze wordt weggelaten. Zie Sandbox-opname voor onderbroken opnamen en volledige bureaubladopname.
Opnamemodi (gerapporteerd in het JSON-veld mode ):
-
wgc— Windows Graphics Capture (standaard; werkt terwijl het venster is afgesloten). -
printwindow— GDI PrintWindow (terugval wanneer WGC niet beschikbaar is op dit systeem/sessie; voer opnieuw uit met--capture-screenschermDOMEINCONTROLLER in plaats daarvan). -
screen— Scherm DC via--capture-screen(inclusief overlays/pop-ups; brengt het venster naar de voorgrond).
JSON-uitvoer (--json):
-
stdout: Uiteindelijke opnameresultaat, inclusief frequentie, stopreden, optioneel
frameArtifactsen waarschuwingen. -
stderr: Eén JSON-object per regel: een
recording-startedgebeurtenis na het eerste frame, gevolgd door een fout als de opname later mislukt. Framepaden worden alleen opgenomen wanneer frameuitvoer actief is.
Foutcodes:
-
element_not_found— De selector komt niet overeen. -
ambiguous_selector— De selector komt overeen met meerdere elementen; gebruik een voorgestelde slug. -
invalid_arguments— Een optiewaarde is ongeldig. -
output_exists— Er bestaat al een opname-uitvoer en kan niet worden vervangen onder de aangevraagde opties. -
frame_output_failed— Geen van beide artefacten kan worden bewaard nadat frameuitvoer is mislukt. -
partial_output— Slechts één artefact voltooid; inspecterenpartialOutputenrecoveryHint.
Een elementkiezer registreert het gebied van dat element in het venster waarin het wordt getekend. Voor een item in een menu, flyout, knopinfo of onderwijstip die in een eigen pop-upvenster wordt geopend, wordt de opname weergegeven in plaats van het venster erachter.
aanroepen
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 Open -w <dialog-HWND> --root Actions --type Button --class-name Button --action invoke
winapp ui invoke SubmitButton -a myapp
Gebruik --action deze opdracht wanneer een test een specifieke bewerking moet uitvoeren op het geselecteerde element. Het probeert nooit een ander patroon of een aanroepbare voorouder, zelfs als de aangevraagde actie mislukt. Een besturingselement dat zowel aanroep als selectie ondersteunt, wordt geselecteerd, niet aangeroepen, met --action select. Met --action, een slug is precies één element; een tekst zonder opmaak of AutomationId-selector die overeenkomt met meer dan één element mislukt gesloten met een niet-nul-afsluitcode in plaats van te handelen op de eerste overeenkomst, dus geef een slug door wanneer inspect/search een naam dubbelzinnig is.
--root, en beperk de overeenkomst zoals beschreven in scoped en getypte query's, met of zonder --action.--class-name--type
Gebruik -w <dialog-HWND> dit om een actie tot dat dialoogvenster te beperken of -a <app> om de vensters van de app op te nemen. Een gefilterde aanroep bevestigt het unieke doel voordat u actie ondergaat, vereist exact één overeenkomend element en schakelt nooit over naar een ander venster of een aanroepbare voorouder. Nulovereenkomsten mislukken met element_not_found; duplicaten mislukken met ambiguous_selector. Een verouderd element of gerecycled venster mislukt zonder te handelen; voer deze opnieuw uit inspect of search kies een huidige selector.
Zonder --actionprobeert een gefilterde aanroep nog steeds de patronen op volgorde van dat ene element.
| Action | Operation |
|---|---|
invoke |
InvokePattern.Invoke |
select |
SelectionItemPattern.Select |
toggle |
TogglePattern.Toggle, precies één keer |
toggle-on / toggle-off |
Lees toggleState; slaagt zonder een al juiste status te wijzigen, anders schakelt u de wisselknop en controleert u |
expand / collapse |
ExpandCollapsePattern.Expand/Collapse |
Voor toggle-on en toggle-off, een beginstatus Indeterminate staat maximaal twee overgangen toe, waarbij de status na elke overgang wordt gecontroleerd. Andere beginstatussen staan één overgang toe. Als de aangevraagde status niet is bereikt, mislukt de opdracht in plaats van door te gaan met schakelen. Een mislukte verificatie kan het besturingselement wijzigen; lees ToggleState voordat u beslist wat u moet doen.
Zonder --action en zonder filters is het automatische gedrag ongewijzigd: probeer InvokePattern, TogglePattern, SelectionItemPattern en vouw vervolgens ExpandCollapsePattern (uit), met een aanroepbare-bovenliggende voorouder opnieuw wanneer dat nodig is.
Een niet-ondersteunde actie mislukt met een niet-nul-afsluitcode en, met --json, een gestructureerde fout op stderr. Inspecteer het geselecteerde besturingselement en kies een actie die het ondersteunt, of richt u expliciet op het beoogde bovenliggende item. Geslaagde JSON bevat requestedAction en performedAction; zie de JSON-verwijzing.
klikken
Klik op een element op de schermcoördinaten met behulp van muissimulatie. Gebruik dit voor besturingselementen die geen ondersteuning bieden InvokePattern (bijvoorbeeld kolomkoppen, lijstitems).
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
Net als de andere invoerinjecterende werkwoorden,
clickbrengt u het doel naar de voorgrond en mislukt u snel (no_interactive_desktopop een vergrendeld/beveiligd bureaublad,foreground_not_targetals de focus niet kan worden overgedragen) in plaats van op het verkeerde venster te klikken. Het element wordt ook opnieuw omgezet vlak voor de knop omlaag: na het plaatsen van de cursor wordt er één laatste positiecontrole uitgevoerd, zodat een continu bewegend/animatief doel mislukt mettarget_movedin plaats van het rapporteren van succes nadat de klik op lege ruimte is terechtgekomen. Een gerapporteerd succes betekent dat het doel nog steeds aanwezig was toen de knop omlaag ging.
Drag
Druk op het ene punt op de muisknop, ga naar het andere en laat vervolgens los met drag <from> <to>, waarbij elk eindpunt een elementselector is (sleept van/naar het midden van het element) of schermcoördinaten x,y precies zoals gerapporteerd door winapp ui inspect. Mix en match vrij (selector→selector, selector→coords, coords→coords).
Wordt SendInput gebruikt met tussenliggende verplaatsingen, zodat de app een realistische stroom berichten WM_MOUSEMOVE ziet. Gebruik deze optie voor het opnieuw ordenen/wijzigen van formaatgrepen, schuifregelaars, tekenpapier en slepen en neerzetten.
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
Opties:
-
--right— Sleep met de rechtermuisknop in plaats van de linkerknop. -
--hold-ms <ms>— Houd de knop aan het begin ingedrukt voordat u gaat bewegen (standaard: 0). Met<from> == <to>(geen beweging) voert dit een druk-en-hold / long-press beweging uit. -
--dwell-ms <ms>— Dwell op de bestemming na verplaatsing, voordat deze wordt vrijgegeven (standaard: 0). Hiermee kunt u doelen verwijderen/overlays samenvoegen die arm van een aanhoudende muisaanwijzer (in plaats van het moment waarop de cursor binnenkomt) vergrendelen voordat de knop omhoog gaat.
Bare
x,yzijn schermcoördinaten in hetzelfde ruimterapportwinapp ui inspect/searchen een selector wordt omgezet in het midden van het element. Inspecteer eerst om punten te kiezen.
Net zoals
send-keys --via send-input,draginjecteert os-brede op schermcoördinaten na het brengen van het doel op de voorgrond. Als de focus niet naar het doel kan worden gebracht (b.v. focus-steeling preventie van een achtergrondproces), mislukt de opdracht (foreground_not_target) in plaats van te slepen op het verkeerde venster: focus of klik eerst op het venster. Op een vergrendeld/beveiligd bureaublad mislukt het metno_interactive_desktop. Elk elementeindpunt wordt onmiddellijk vóór de sleep opnieuw omgezet; als de opdracht nog steeds wordt verplaatst/verkleind (een animatiedoel), mislukt de opdracht intarget_movedplaats van naar een verlopen punt te slepen. (Legex,yeindpunten kunnen niet opnieuw worden geverifieerd, zodat ze worden gebruikt as-is.)
Aanraken
Injecteer synthetische aanraakbewegingen met behulp van de Windows aanwijzer-injectie-API. Het anker voor contactpersonen is een elementkiezer (gebruikt het midden van het element) of een expliciet schermcoördinaat x,y via --at (dezelfde ruimterapporten winapp ui inspect ). Gebruik deze functie voor tikken/drukken op interacties en bewegingen met meerdere aanraakbewegingen die de muissimulatie niet kan uitdrukken.
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)
Opties:
-
--gesture <g>—tap(standaard),double-tap,long-press,swipe, ,pinch.stretch -
--at <x,y>— Expliciet beginpunt (schermcoördinaten). De standaardinstelling is het elementcentrum van de selector. -
--to-point <x,y>— Eindpunt voor eenswipe. Heeft voorrang op--direction. -
--direction <right|left|up|down>— Veegrichting (standaard:right). Gecombineerd met--distancehet berekenen van het eindpunt wanneer--to-pointdit niet is opgegeven. -
--distance <px>— Vinger verspreid voorpinch/stretchof veeg afstand in pixels. -
--hold-ms <ms>— Houd contactpersonen ingedrukt voordat u opheft (houd de tijd lang ingedrukt; de standaardwaarde is 500 ms voorlong-presswanneer deze niet is ingesteld). -
--duration-ms <ms>— Glide tijd voor bewegende bewegingen (veeg/knijp/stretch; standaard 300). -
--fingers <n>— Aantal contactpersonen (1-10; standaard 1).pinch/stretchgebruik altijd 2.
Injectieveiligheid.
touchweigert te injecteren tenzij een niet-nul doelvenstergreep wordt omgezet en dat venster de voorgrond bevat. Het mislukt wanneerno_targeter geen venster kan worden omgezet,foreground_not_targetals de focus niet kan worden overgedragen ofno_interactive_desktopop een vergrendeld/beveiligd bureaublad. Elke coördinaat (elementcentrum, expliciet--at/--to-pointen gegenereerde waypoints) wordt gecontroleerd op de rechthoek van het doelvenster; een punt buiten het venster wordt weergegeven als een niet-fatale waarschuwing (eenwarnings[]vermelding in--json, of een waarschuwingslijn in de tekstmodus) en de injectie gaat nog steeds verder , die overeenkomt met de muiswoorden (click/drag/hover/scroll), die ook in out-of-window-coördinaten injecteert.--fingersboven de 10 wordt vooraf geweigerd.Hardwarenotitie. Touch geeft de voorkeur aan het moderne synthetische aanwijzerapparaat (
CreateSyntheticPointerDevice(PT_TOUCH)) en valt terug op de verouderdeInitializeTouchInjection/InjectTouchInputAPI. Als injectie niet wordt ondersteund op het huidige apparaat/de huidige sessie, wordt met de opdracht de daadwerkelijke Win32-foutcode (bijvoorbeeld 'niet-ondersteund') weergegeven in plaats van een foutief succes te melden. Behandel een niet-nul-uitgang als 'touch not delivered'.Extern bureaublad/VM-sessies. In een Extern bureaublad (RDP) of sommige VM-sessies kan het besturingssysteem synthetische aanraking (exit 0) accepteren zonder dat het daadwerkelijk de doel-app bereikt. Wanneer een externe sessie wordt gedetecteerd,
touchvoegt u een waarschuwing over leveringsonzekerheid toe, eenwarnings[]vermelding in--jsonof een waarschuwingsregel in de tekstmodus. Een ✅/exit 0 betekent dan dat de injectie-aanroep is geslaagd, niet dat de app de invoer heeft ontvangen; bevestig het effect metui screenshot/ui inspectwanneer het belangrijk is.
pen
Injecteer synthetische pen-/stylusinvoer — tikken en pennenstreken — met behulp van de Windows synthetische aanwijzer-API (CreateSyntheticPointerDevice(PT_PEN); Windows 10 1809+). Richt u op een elementcentrum, een expliciet --at punt of een volledige --path pennenstreek.
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
Opties:
-
--at <x,y>— Pencontactpunt (schermcoördinaten). De standaardinstelling is het elementcentrum van de selector. Genegeerd wanneer--pathwordt gegeven. -
--path "<x,y x,y …>"— Pennenstrekenpad als spaties gescheidenx,yparen (een pad met één punt is een tik). -
--pressure <0.0–1.0>— Pendruk (standaard 0,5). -
--tilt-x <deg>/--tilt-y <deg>— Kantelhoeken van pen, −90 tot 90 (standaard 0). -
--eraser— Gebruik het gumeinde van de pen in plaats van de tip. -
--duration-ms <ms>— Totale reistijd voor pennenstreken in milliseconden verdeeld als geïnterpoleerde UPDATE-frames over het pad (standaard: ~10 ms per waypoint). Gebruik deze optie om te bepalen hoe snel de pen zichtbaar van begin tot eind beweegt.
Injectieveiligheid. Zoals
touch,penweigert te injecteren zonder een niet-nul, voorgronds doelvenster (no_target/foreground_not_target/no_interactive_desktop) en controleert elk inktpunt tegen de rechthoek van het doelvenster, waarbij een out-of-window coördinaat wordt weergegeven als een niet-fatale waarschuwing (warnings[]in--json, of een waarschuwingsregel in de tekstmodus) terwijl er nog steeds wordt geïnjecteerd , consistent met de muiswoorden. Ongeldig--pressure(buiten 0,0–1.0) of kantelen (buiten ±90°) worden vooraan geweigerd.Extern bureaublad/VM-sessies. Penroutering is vooral onbetrouwbaar ten opzichte van Extern bureaublad: de injectieaanroep kan slagen (exit 0) melden terwijl er geen peninvoer de app bereikt. Wanneer een externe sessie wordt gedetecteerd,
penvoegt u een waarschuwing over bezorgingsonzekerheid (warnings[]in--jsonof een waarschuwingsregel in de tekstmodus) toe, zodat een ✅ waarschuwing niet wordt verward met bevestigde bezorging. Valideer penafhankelijke stromen op een lokaal, interactief bureaublad.
aanwijzen
Verplaats de muis naar het midden van een element om aanwijseffecten te activeren (knopinfo, flyouts, visuele statussen). Gebruikt SendInput voor realistische muisbewegingen met een kleine pruik en wacht vervolgens op een configureerbare woningtijd.
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
Opties:
-
--dwell-time <ms>— Tijd in milliseconden om te wachten na het aanwijzen van effecten (standaard: 800, bereik: 0-10000)
send-keys
Synthetische toetsenbordinvoer verzenden - de tegenhanger van het toetsenbord naar click. UIA heeft geen toetsenbordinjectiepatroon, dus dit zakt naar de Win32-laag. Gebruik dit voor toetsenbordnavigatie (pijlen, Tab, Enter, Esc), sneltoetsen (ctrl+c, alt+f4) en typen in besturingselementen die per toetsaanslagen gebeurtenissen nodig hebben in plaats set-valuevan atomische schrijfbewerkingen.
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
winapp ui send-keys "ctrl+capslock+f12" -a myapp --via send-input # Narrator command: toggle developer mode
Sleutel grammatica (witruimte-gescheiden tokens, aanhalingstekens met meerdere tokentekenreeksen):
-
Benoemde sleutels : ,
enter/returntabesc/escapespace,backspacedelete/delinserthomeend,pageup/pgup,pagedown/pgdnup/down/left/rightf1, –f16apps, .printscreencapslock -
Reeksen : meerdere tokens worden op volgorde ingedrukt:
down down enter. -
Modifier combos — ,
ctrl,shift,altwinsamengevoegd met+:ctrl+shift+t, .alt+f4Een token dat begint met een wijzigingsfunctie, maar een onbekend segment heeft voordat het laatste (ctrl+a+b) een fout is; gebruikentext=of--verbatimtypen. -
Opdrachten voor schermlezers : de
capslockinsertinsVerteller-, NVDA- en JAWS-sleutelctrl+capslock+f12: schakelt de verteller-ontwikkelaarsmodus in. Vereist--via send-input, omdat schermlezers geen geplaatste sleutels ontvangen. Als er geen schermlezer wordt uitgevoerd,capslockschakelt u Caps Lock in of uit en waarschuwt u de opdracht. Houdinsertdit vast om dit te voorkomen. -
Letterlijke tekst : een token dat geen bekende sleutel is, wordt per teken getypt:
hello. Aangrenzende letterlijke woorden houden de spatie ertussen, zodat een woordgroep tussen aanhalingstekens zoals"Hello world"woordgroepen wordt getypt (de spatie blijft behouden); een letterlijke waarde die alleen tekst bevat+C++ofa+bals tekst is getypt, niet geparseerd als een combinatie. -
Expliciete letterlijke escape - het voorvoegsel van een token om
text=deze letterlijk te typen, zelfs wanneer het conflicteert met een sleutel- of wijzigingsnaam:text=entertypt het woord 'enter' in plaats van op Enter te drukken entext=ctrl+atypt de letterlijke tekenreeks. Hiermee wordt devk=escape gespiegeld; de escape-waarde wordt nog steeds samengevoegd met aangrenzende letterlijke woorden (text=down low→ 'laag omlaag'). Omdat tokens spaties splitsen (en aangrenzende letterlijke waarden opnieuw samenvoegen met één spatie), gebruikt u backslash-escapes in eentext=waarde om witruimte te typen die anders niet zou overleven:\s→ spatie,\t→ tabblad,\n→ nieuwe regel,\r→ nieuwe regel,\\→ letterlijke backslash.\n,\ren\r\nelke regel een regeleinde (een Enter/VK_RETURN), dustext=line1\nline2entext=line1\r\nline2beide typen één nieuwe regel. Typtext=a\s\sbdus 'a b' (dubbele spatie) entext=\shihoudt een voorloopruimte. Een niet-herkende ontsnapping (bijvoorbeeld\x) is letterlijk. -
Geheel argument letterlijk (
--verbatim) - wanneer de hele nettolading letterlijke tekst is, geeft u door--verbatimin plaats van elk token mettext=te ontsnappen. Het typt het argument voor de hele sleutels precies zoals opgegeven , geen benoemde sleutel / combinatie /vk=/text=interpretatie - en, in tegenstelling tot het normale pad, behoudt exacte interne witruimte (geen samenvouwen) zonder dat dit nodig is.\sTypsend-keys "down down enter" --verbatimdus de woorden ensend-keys "a b" --verbatimhoudt de dubbele spatie. Backslash-escapes worden niet gedecodeerd in--verbatimde modus (een\sis getypt als een backslash en een 's'); gebruik een token wanneer u eentext=escaped-besturingselementteken nodig hebt. -
Onbewerkte virtuele sleutels (
vk=0xNNhex) ofvk=NN(decimaal) voor sleutels zonder een beschrijvende naam.
Opties:
-
--target <selector>— Richt dit element (via UIA) voordat u sleutels verzendt. Zonder dit gaat u naar het momenteel gerichte element van de app. -
--verbatim— Typ het hele toetsenargument als letterlijke tekst (geen sleutel/combinatie/vk=/text=parsering) en behoud exacte witruimte. De gehele argumentvorm van de escape per tokentext=. -
--via <transport>—post-message(standaard) berichtenWM_KEYDOWN/WM_KEYUP/WM_CHARin de wachtrij van het doelvenster. Het is gericht op HWND en omzeilt UIPI (werkt tussen integriteitsniveaus).send-inputinjecteert het besturingssysteem breed viaSendInputen gaat naar het voorgrondvenster.
Een transport/ bekende limieten kiezen:
-
post-messageis de standaardinstelling omdat uiPI wordt omzeild en niet afhankelijk is van het venster op de voorgrond. Limieten: er kunnen geen globale sneltoetsen worden geactiveerd die zijn geregistreerd viaWH_KEYBOARD_LLhooks op laag niveau (die tikken op invoer upstream van een vensterwachtrij) en apps die de status van onbewerkte sleutel lezen viaGetAsyncKeyState, kunnen mogelijk geen heldsaanpassingen observeren. Het lost automatisch op en plaatst berichten in het gerichte onderliggende venster van de doelthread (viaGetGUIThreadInfo) na voorgronding, dus klassieke Win32/WinForms-apps waarvan de besturingselementen afzonderlijke onderliggende vensters zijn, ontvangen sleutels zonder handmatig gericht op het besturingselement. WinUI 3/UWP-apps hebben vensterloze XAML-besturingselementen zonder onderliggende HWND, dus een geplaatste appWM_CHAR/WM_KEYDOWNheeft niets om binnen te komen en wordt verwijderd. Post-message kan ze niet sturen (de opdracht waarschuwt en sluit 0); gebruik .--via send-input(WPF vensters zijn single-HWND en routesleutels naar het intern gerichte element, dus post-message werkt daar.) -
send-inputproduceert volledig echte invoer (modifiers zichtbaar voorGetAsyncKeyState, brandt haakjes op laag niveau) maar gaat naar het venster dat voorgrond is en wordt geblokkeerd door UIPI bij het injecteren van een verhoogd proces in een AppContainer/AppX-doel. Alssend-inputer een fout wordt gerapporteerd, is het doel waarschijnlijk verhoogd of een AppX-app. Gebruikpost-messageof voer de CLI uit op een overeenkomend integriteitsniveau. Als veiligheidsbeveiligingsend-inputcontroleert u of het doelvenster zich direct op de voorgrond bevindt voordat u het injecteert en mislukt (foreground_not_target) in plaats van in het verkeerde venster te typen als de focus niet naar het venster kan worden gebracht : focus of klik eerst op het venster. Op een vergrendeld of beveiligd bureaublad mislukt het in plaats daarvan metno_interactive_desktop(er bestaat geen voorgrondvenster om in te injecteren) - ontgrendel de sessie of gebruik een UIA-patroonwoord (set-value,invoke). -
Systeem gereserveerde combinaties (
win+l,win+r,ctrl+shift+esc,ctrl+alt+del,alt+tab, ,alt+f4ctrl+esclonewin/printscreen, ...) handelen op het besturingssysteem/shell in plaats van alleen het doel wanneer het besturingssysteem breed wordt verzonden.send-inputnegeert ze standaard (fouten metinvalid_argumentsen verzendt niets), omdat het injecteren ervan op het niveau van het besturingssysteem veel meer dan het doelvenster heeft (bijvoorbeeldwin+lde sessie vergrendelt). Pass--allow-system-keysto opt in — hiermee kunt u een globale sneltoets zoals PowerToys'win+shift+vofwin+r(de wereldwijde haak op laag niveau kijkt naar de invoerstroom van het besturingssysteem, zodat de geïnjecteerde combinatie deze brandt). Uitzonderingen die geblokkeerd blijven, zelfs bij--allow-system-keys:win+lvergrendelt het werkstation viaLockWorkStation()welke niet kan worden hersteld door automatisering (breekt CI- en extern bureaubladsessies) enctrl+alt+delis een SAS (Secure Attention Sequence) die Windows daalt van geïnjecteerde invoer, ongeacht de vlag, het kan nooit van kracht worden, zodat het fouten (invalid_argumentssluit 1) in plaats van een misleidend succes te melden. Andere combinaties (alt+f4,ctrl+shift+esc,win+r, ...) worden toegestaan met de vlag - bewareer. Als u een systeemcombinatie wilt leveren aan een specifiek venstergebruik--via post-message, wat vensterbereik heeft en niet wordt beïnvloed (een geplaatste iswin+longevaarlijk, hoewel een geplaatste hetalt+f4doelvenster nog steeds sluit).
Gebeurtenissen per toetsaanslag (KeyDown/ TextChanged):
-
Benoemde sleutels en wijzigingscombinaties (
down,enter,ctrl+shift+t,vk=0xNN) activeren een echteKeyDown(enKeyUp) op beide transporten: ze worden geleverd als discreteWM_KEYDOWN/WM_KEYUP(ofSendInputvirtuele-sleutelgebeurtenissen). -
Letterlijk getypte tekst (
hello) verschilt per transport:-
--via send-inputwijst elk teken toe aan de virtuele toets (plus Shift) in de actieve toetsenbordindeling, zodat het doel een echteKeyDownvirtuele toets ziet met de juiste virtuele toets , gevolgd door het op het besturingssysteem samengesteldeWM_CHAR(verhogendeTextChanged) - dat wil bijvoorbeeld één volledige toetsaanslag per teken. Tekens die niet bereikbaar zijn in de huidige indeling (of ctrl/AltGr) moeten terugvallen op een Unicode-pakket, zodat het exacte teken nog steeds terechtkomt. Gebruiksend-inputdeze optie wanneer u per toetsaanslagenKeyDownbetrouwbaarheid nodig hebt (bijvoorbeeld het rijden van een WinUI 3 / WPFTextBoxwaarvan de handlers worden uitgeschakeldKeyDown). Voor een normale (niet-verhoogde) WinUI 3-testhost brengt u het venster eerst naar de voorgrond (winapp ui focus/erop klikken) omdatsend-inputhet gericht is op het voorgrondvenster. -
--via post-messageplaatst éénWM_CHARper teken (deze post nietWM_KEYDOWN/WM_KEYUPvoor getypte tekst, die zijn gereserveerd voor benoemde sleutels/combo's), waardoor er geen per tekenKeyDownwordt gegenereerd. Het wordt automatisch opnieuw gericht op het onderliggende besturingselement van het venster, dus klassieke Besturingselementen voor Win32/WinFormsWM_CHAR-driven edit landt de tekst (verhogenTextChanged). Caveat: WinUI 3 / UWP / XAML-apps (winapp's primaire doel) hebben vensterloze besturingselementen die wordenWM_CHAR/WM_KEYDOWNgenegeerd, dus geen letterlijke tekst of benoemde sleutels (Enter, cijfers, ...) bereiken ze, ook al rapporteert de opdracht is geslaagd. Er wordt een waarschuwing verzonden wanneer het doel eruitziet als XAML en nog steeds 0 afsluit (PostMessageis fire-and-forget en kan de levering niet bevestigen). Gebruik--via send-inputdit om WinUI 3/UWP/WPF-apps aan te sturen; reserveerpost-messagevoor klassieke Win32-besturingselementen of wanneer u deze alleen vensterbereiken nodig hebt voor integriteitsniveaus.
-
JSON-uitvoer (--json): het resultaat hwnd is het effectieve venster waarin de sleutels zijn geleverd. Voor --via post-message dit is het opgeloste onderliggende besturingselement met prioriteit wanneer de opdracht opnieuw wordt gericht (niet noodzakelijkerwijs het venster op het hoogste niveau-w/-a/-e), zodat automatisering precies kan bevestigen waar de invoer terecht isgekomen. Wanneer dit effectieve doel eruitziet als een vensterloze XAML-host, wordt de bovenstaande leveringsfout ook weergegeven als een warnings[] vermelding (hetzelfde advies dat op de console wordt weergegeven), zodat een ✅ uitgang 0 niet wordt verward voor bevestigde levering.
set-value
Stel een waarde in op een bewerkbaar element programmatisch (geen toetsaanslagen, geen app voorgrond). Maakt gebruik van een terugvalketen:
- ValuePattern : tekstvak, keuzelijst met invoervak, wachtwoordvak en de meeste bewerkbare besturingselementen.
- RangeValuePattern : numerieke besturingselementen (schuifregelaar, voortgangsbalk) wanneer de waarde als een getal wordt geparseerd.
-
LegacyIAccessible (
IAccessible::put_accValue) - de terugval voor besturingselementen voor alleen textPattern-bewerkingen die geen ValuePattern beschikbaar maken (bijvoorbeeld rich-edit/Documentcompose boxes). Hierdoor wordt de lees-/schrijfruimte gesloten waarget-valueeen dergelijk besturingselement kan worden gelezen, maarset-valueniet.
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
Als geen van de drie patronen de waarde kan instellen, set-value mislukt het met een duidelijke fout die send-keys wijst als laatste redmiddel.
Niet elke uitgebreide editor ondersteunt programmatische set. De LegacyIAccessible-terugval werkt alleen op besturingselementen waarvan de toegankelijkheid implementeert
IAccessible::put_accValue: systeemeigen Besturingselementen voor uitgebreide bewerking en Chromium/Electron/WebView2 opstellen oppervlakken meestal. WinUI 3RichEditBoxen WPFRichTextBoxbieden geen ondersteuning voor programmatische waarde-instelling. Ze maken hun inhoud standaard zichtbaar voor UI Automation als alleen-lezen (tekstpatroon, geen settabelwaardepatroon), zodatset-valueze er niet naar kunnen schrijven. Gebruiksend-keys(waarvoor een ontgrendeld bureaublad op de voorgrond nodig is) voor deze.
get-value
Lees de huidige waarde van een element. Maakt gebruik van een slimme terugvalketen: TextPattern (RichEditBox, Document) → ValuePattern (TextBox, Slider) → SelectionPattern (ComboBox, RadioButton, TabView) → Naam (labels).
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
Een leeg tekstveld retourneert, niet het toegankelijkheidslabel "text": "". Inhoud met alleen witruimten blijft ook behouden in JSON.
wait-for --value "" komt overeen met een leeg veld, ongeacht of het nieuw is of is gewist na het bewerken. Als u in plaats daarvan het toegankelijkheidslabel wilt lezen, gebruikt u get-property --property Name.
focus
winapp ui focus txt-textbox-a4b1 -a notepad
Activeert het venster van het geselecteerde besturingselement wanneer dat nodig is en richt het besturingselement vervolgens op.
De selector is vereist; gebruik -a <app> of -w <HWND> kies het doel.
Geslaagd betekent dat het venster voorgrond was en het geselecteerde besturingselement bevestigd HasKeyboardFocus voordat de opdracht werd geretourneerd. Met de opdracht kan het besturingselement maximaal 500 ms de focus geven; het stopt als het doel verdwijnt of de voorgrond verliest in plaats van de focus terug te nemen. Een dialoogvenster in eigendom voor het hoofdvenster is niet voldoende: selecteer een besturingselement in het dialoogvenster als dat uw doel is.
Deze opdracht heeft een ontgrendeld, interactief bureaublad nodig en slaat Windows activeringsbeperkingen niet over. Als dit mislukt, foreground_not_targetactiveert u het beoogde venster handmatig en controleert u op een blokkeringsdialoogvenster voordat u het opnieuw probeert.
Inspecteer focus_not_acquiredde huidige gebruikersinterface en kies een focusbaar besturingselement.
Voor stale_element, herontdekt het doel met inspect of search.
Houd hetzelfde --on doel bij detectie- en nieuwe opdrachten.
scroll-into-view
Schuif een element naar het zichtbare gebied.
winapp ui scroll-into-view itm-targetitem-c3d4 -a myapp
wachten op
Wacht tot een element wordt weergegeven, verdwijnt of heeft een waarde een doel bereikt.
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
Schuiven
Schuif door een containerelement. Schuifbare containers zoeken met search scroll : zoek [scroll:v] naar (verticale) of [scroll:h] (horizontale) markeringen.
# 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
Opties:
-
--direction <up|down|left|right>— Schuif stapsgewijs viaScrollPattern. -
--to <top|bottom>— Ga naar het begin/einde viaScrollPattern. -
--wheel <notches>— Synthetiseer de invoer van het muiswiel over het midden van het element viaSendInput, in wielkepingen (tenten):1= één inkeping omhoog/weg,-1= één inkeping naar beneden/naar,3= drie inkepingen omhoog. (Elke notch is de WindowsWHEEL_DELTAvan 120 eenheden dieSendInputverbruiken; de CLI schaalt met 120 voor u.) OmzeiltScrollPattern.
--direction,--toen--wheelsluiten elkaar wederzijds uit - geef precies één door. Omdat--wheelhet besturingssysteembrede invoer op schermcoördinaten injecteert, wordt het doel eerst op de voorgrond geplaatst en mislukt (foreground_not_target) als de focus niet kan worden overgedragen, in plaats van het verkeerde venster te schuiven.
get-focused
winapp ui get-focused -a myapp
winapp ui get-focused -w <HWND> --json
Het element weergeven dat momenteel de toetsenbordfocus heeft in de geselecteerde app, inclusief besturingselementen waarvan het eigendom van de app alleen beschikbaar is via het bovenliggende venster.
Met -w, focus moet behoren tot dat venster, niet een ander venster of een pop-up in eigendom in hetzelfde proces. Met -a, andere vensters in het geselecteerde proces zijn opgenomen.
JSON-uitvoer heeft hasFocus:false wanneer er geen gericht element kan worden geverifieerd als behorend tot het doel. Als een query voor focus- of venstereigendom mislukt, sluit de opdracht in plaats daarvan niet-nul; probeer get-focusedhet opnieuw en herontdek het venster opnieuw als list-windows het is gesloten.
list-windows
Alle zichtbare vensters voor een app weergeven, inclusief pop-ups en dialoogvensters. Standaard worden naamloze vensters met nulgrootte (onzichtbare systeemvensters) uitgesloten.
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
rendement
Laat de gebruikersinterface van deze werkstroom vroeg in plaats van wachten op de niet-actieve respijt van vier seconden. Vereist WINAPP_UI_WORKFLOW_ID; neemt geen app en geen selector. Zie De beurt vroeg vrijgeven.
winapp ui yield
winapp ui yield --json # {"released": true} — or false when nothing was held
Framework-ondersteuning
| Raamwerk | Inspecteren | search | aanroepen | set-value | schermopname |
|---|---|---|---|---|---|
| WPF | ✅ Volledige structuur | ✅ Alle eigenschappen | ✅ Alle patronen | ✅ ¹ | ✅ |
| WinForms | ✅ | ✅ | ✅ | ✅ | ✅ |
| Win32 | ✅ | ✅ | ✅ | ✅ | ✅ |
| WinUI 3 | ✅ | ✅ | ✅ | ✅ ¹ | ✅ |
| Elektron | ⚠✍ Chroomboom | ⚠️ Beperkt | ⚠ϑ varieert | ⚠ϑ varieert | ✅ |
| Flutter | ⚠️ Basis | ⚠️ Basis | ❌ Minimale | ❌ | ✅ |
¹ set-value werkt op elk besturingselement dat ValuePattern/RangeValuePattern weergeeft, plus besturingselementen voor bewerken met alleen TextPattern waarvan de toegankelijkheid wordt geïmplementeerd IAccessible::put_accValue (LegacyIAccessible fallback).
WinUI 3 RichEditBox en WPF RichTextBox zijn uitzonderingen: ze maken alleen het alleen-lezen tekstpatroon (geen instelbaar waardepatroon) beschikbaar, zodat ze niet programmatisch kunnen worden ingesteld op basis van ontwerp; gebruik send-keys (interactief bureaublad vereist) om erin te typen.
De engine gebruiken vanuit uw eigen code
Alles winapp ui is beschikbaar als bibliotheek, zodat u dezelfde automatisering kunt uitvoeren vanuit een test of hulpprogramma zonder dat u naar de CLI hoeft te gaan:
| Package | Wat het toevoegt |
|---|---|
Microsoft.Windows.SDK.BuildTools.WinApp.UIAutomation |
Inspectie, selectors, interactie met UIA-patroon, invoerinjectie, schermopnamen |
Microsoft.Windows.SDK.BuildTools.WinApp.UIAutomation.Recording |
Video-opname naar MP4, plus framebundels |
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);
Gebruik voor deterministische acties de overbelasting: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 negeert dubbelzinnige tekst in plaats van een aanroepbare overeenkomst te kiezen. Exacte AutomationId-overeenkomsten hebben voorrang op naam- of AutomationId-subtekenreeksen; een unieke naam kan nog steeds een besturingselement selecteren waarvan AutomationId wordt gedeeld.
Voor een doel binnen het bereik van een app wordt alle bijbehorende app-/eigendomvensters gecontroleerd. Gebruik -w <HWND> (of een expliciet bibliotheekdoel) om het selectiebereik te beperken.
Het retourneert Pattern en PerformedAction met dezelfde betekenis als het CLI-actieresultaat.
Geef een element door dat wordt geretourneerd door inspectie of selectie, met de runtime slug of unieke AutomationId intact. Expliciete acties weigeren een ontbrekende of dubbelzinnige identiteit in plaats van opnieuw te verbinden op naam en type besturingselement.
Voor leesbereiken stelt u deze in UiSelector.Root op een andere UiSelector, ControlType op een typenaam en ClassName op de letterlijke providerklasse. Deze gebruiken dezelfde querypredicaten als de CLI. Er wordt slechts één hoofdniveau ondersteund: selector.Root.Root moet zijn null. Een geneste hoofdmap gooit voordat het doelvenster wordt opgezoekd ArgumentException . Gebruik een unieke root AutomationId of slug in plaats van wortelkiezers te nesten.
UiControlTypes.GetId(name) lost officiële typenamen en de twee gedocumenteerde aliassen op, die worden geretourneerd 0 voor een ongeldige naam.
UiControlTypes.GetName(id) retourneert de canonieke naam of Unknown(id) voor een niet-herkende id.
Wanneer u een UiElement herstelde JSON doorgeeft aan GetTextAsync of GetPropertiesAsync, behoudt u het Selector en WindowHandle. Een slugselector moet nog steeds het oorspronkelijke element identificeren; als deze niet meer bestaat, worden deze gelezen in UiElementNotFoundException plaats van een ander element met dezelfde AutomationId of naam te selecteren. Voer de oorspronkelijke query opnieuw uit om het resultaat te vernieuwen. Met leesbereik worden ook fouten doorgegeven van algemene UIA-eigenschappen getters en verkregen UIA-patronen in plaats van null of een eerder vastgelegde waarde te retourneren.
Opnemen is een afzonderlijk pakket, zodat projecten die alleen de gebruikersinterface van SkiaSharp inspecteren en stationen niet ophalen. Het automatiseringspakket is zowel net10.0-windowsnet10.0-windows10.0.19041.0gericht op als ; de laatste voegt Windows Graphics Capture toe, wat inhoudt dat screenshot occluded of GPU-samengestelde windows kan worden vastgelegd. Bekijk de README van elk pakket op NuGet voor de volledige API en het doelframework.
UiTarget.FromWindowHandleis het ingangspunt voor testframeworks waarmee u al een venster hebt, bijvoorbeeld MSTest.Windows.UIAutomationwaarvan WindowTest.MainWindow u een UIA2 AutomationElement overbrugt.MainWindow.Current.NativeWindowHandle
Troubleshooting
| Fout | Oorzaak | Oplossing |
|---|---|---|
| "Er is geen actieve app gevonden" | App wordt niet uitgevoerd of de naam komt niet overeen | Procesnaam controleren of PID gebruiken |
| "Meerdere vensters komen overeen" | Dubbelzinnige -a waarde |
Gebruiken -w <HWND> vanuit de vermelde opties |
| "heeft meerdere vensters" | Proces heeft meerdere vensters | Gebruiken -w <HWND> om een specifiek doel te bereiken |
| "Selector matched N elements" | Dubbelzinnige verouderde selector | Slugs uit inspect uitvoer gebruiken of toevoegen [0]aan [1] verouderde selectors |
| "Element kan zijn gewijzigd" | Slug-hash komt niet overeen met het huidige element | Opnieuw uitvoeren inspect of search verse slugs krijgen |
| "biedt geen ondersteuning voor een aanroeppatroon" | Het element kan niet worden aangeroepen | Op inspect het element gebruiken om een aanroepbaar onderliggend element te zoeken |
| "Geen UIA-venster gevonden" | UIA kan het proces niet zien | Gebruik list-windows deze om de HWND te vinden en vervolgens -w |
| "Venster heeft nulgrootte" | Venster is geminimaliseerd | De app wordt automatisch hersteld |
| Pop-up/vervolgkeuzelijst niet in schermopname | Standaardopname is per venster en bevat geen niet-gekoppelde overlays | Volg de overlaywerkstroom voor schermopnamen om een venster te selecteren met -w <hwnd> --capture-screen |
foreground_not_target van --capture-screen |
Windows de activering geweigerd, zodat een schermopname zou hebben opgenomen welk venster zich daadwerkelijk vooraan bevindt | Klik op het doelvenster of sluit het focusdiefstalvenster en probeer het opnieuw of verwijder --capture-screen |
element_not_found tijdens record |
Opgegeven selector, maar geen overeenkomend element | Opnieuw uitvoeren inspect of search een nieuwe selector ophalen |
| WGC niet beschikbaar tijdens record | WGC capture init is mislukt; geen stille terugval | GPU/stuurprogramma controleren; gebruiken --capture-screen om toestemming te geven voor scherm-DC-opname |
Algemene patronen
Navigeren en controleren
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
Tekst zoeken en het bovenliggende item aanroepen
# 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
Dubbele elementen ondubbelzinnig maken
winapp ui search '#Image' -a myapp; winapp ui invoke itm-image-a2b3 -a myapp
Schermopname met pop-up-overlays
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
Navigeren, wachten en controleren (enkele keten)
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
Ontdekken, klikken en controleren
winapp ui inspect -a myapp --interactive; winapp ui invoke btn-submit-7a90 -a myapp; winapp ui screenshot -a myapp
Interactie in dialoogvenster Bestand
Dialoogvensters voor openen/opslaan van bestanden zijn standaarddialoogvensters Windows met UIA-ondersteuning:
# 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>
Gebruik inspect -w <dialog-hwnd> --interactive deze functie om de werkelijke slugs voor een specifiek dialoogvenster te ontdekken.
Waarom ; ketenen (niet &&)
De operator van && PowerShell kan blokkeren wanneer een systeemeigen CLI schrijft naar stderr of ANSI-escapereeksen gebruikt. In ; plaats daarvan wordt elke opdracht voorwaardelijke uitgevoerd en wordt deze impasse vermeden. Dit is ook beter voor agentwerkstromen: meestal wilt u dat de schermafbeelding wordt uitgevoerd, zelfs als de aanroep een afsluit zonder nul heeft.
CI-testpatronen
Gebruik winapp ui opdrachten in CI-pijplijnen (GitHub Actions, Azure DevOps) voor betrouwbaarheidstests en ui-validatie.
wait-for met --property en --value fungeert als een assertie: het retourneert afsluitcode 1 bij time-out, waarbij de CI-stap automatisch mislukt.
Starten en testen in 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
Status van element assertie met wait-for
wait-for --value pollt totdat de waarde van een element overeenkomt met de verwachte tekenreeks, waarbij dezelfde slimme terugval wordt gebruikt als get-value (TextPattern → ValuePattern → SelectionPattern → Name). Retourneert afsluitcode 0 bij overeenkomst, afsluitcode 1 bij time-out, waardoor deze een CI-vriendelijke assertie is. Gebruik --property in plaats daarvan om een specifieke UIA-eigenschap te controleren.
# 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 met JSON-uitvoer
Gebruik --json met PowerShell of jq voor complexere asserties:
Afsluitcodecontract voor
searchenwait-forin--jsonde modus: als er geen element overeenkomt (search) of de wachttijd (wait-for), schrijft de opdracht een volledig parseerbare resultaatenvelop naar stdout ({ "matchCount": 0, ... }of{ "found": false, "timedOut": true, ... }) en retourneert afsluitcode 1. Stderr is leeg in--jsonde modus (loggeruitvoer wordt onderdrukt). Vertakking op de envelopvelden, of op$LASTEXITCODE, afhankelijk van welke ergonomischer is.
# 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" }
De JSON-enveloppen zijn:
-
inspect:{ "depth", "interactive", "hideDisabled", "hideOffscreen", "windows": [...] } -
search:{ "matchCount", "hasMore", "matches": [...] } -
wait-for:{ "found", "waitedMs", "element"?, "timedOut" } -
get-property:{ "elementId", "element", "properties": { ... } }
Getypte elementen gebruiken type en numeriek x, y, widthen height.
Geometrie bevindt zich in fysieke scherm pixels.
0,0,0,0is UI Automation lege/no-displayed-UI-rechthoek in deze projectie; isOffscreen is gescheiden, zodat een offscreen-element nog steeds niet-nulgrenzen kan hebben.
Elke inspect --jsonwindows[] vermelding en het status --json resultaat bevatten windowDpi, scale (windowDpi / 96), dpiAwarenessen coordinateSpace: "physical-screen-pixels". Deze beschrijven de DPI-context van het doelvenster, niet onvoorwaardelijke monitor DPI: Windows rapporteert 96 voor een niet-bewust venster, systeem-DPI voor een systeembewust venster en de huidige monitor DPI voor een per monitorbewust venster. Als de HWND- of DPI-context niet kan worden gelezen, mislukt de opdracht in plaats van 96 op de achtergrond te vervangen. Wanneer status een proces wordt omgezet voordat het een venster op het hoogste niveau heeft, hwnd worden 0 de DPI-velden weggelaten totdat er een venster bestaat. Voor procesbreed inspectblijft het geselecteerde doelvenster fail-fast. Als een latere pop-up verdwijnt nadat de structuur is gelezen, windows[] worden dpiError de DPI-velden door de vermelding verplaatst en weggelaten terwijl de resterende vensterstructuren nog steeds worden geretourneerd.
Zie de verzonden winapp-ui-automation vaardigheid voor references/ui-json-envelope.md volledige voorbeelden van elke envelop.
Voorbeeld van een volledige betrouwbaarheidstest
# Launch
$app = winapp run .\build-output --detach --json | ConvertFrom-Json
# Verify app loaded
winapp ui wait-for "Main Page" -a $app.ProcessId -t 30000
# Interact and assert
winapp ui invoke "Add Item" -a $app.ProcessId
winapp ui set-value "Item Name" "Test Item" -a $app.ProcessId
winapp ui invoke "Save" -a $app.ProcessId
winapp ui wait-for "Test Item" -a $app.ProcessId -t 5000 # assert item appeared in list
winapp ui wait-for "Save" -a $app.ProcessId --gone -t 3000 # assert save dialog closed
# Visual verification
winapp ui screenshot -a $app.ProcessId -o smoke-test.png
Windows developer