Not only in the Get-UIA[ControlType] cmdlet family were introduced improvements. Another veteran, the Get-UIAWindow cmdlet has been modernized.
This is a start place for our experiments:
# there's an application with two forms open Start-Process calc -PassThru | Get-UIAWindow | Get-UIAMenuItem help | Invoke-UIAMenuItemExpand | Get-UIAMenuItem -n about* | Invoke-UIAMenuItemClick;
# using the Get-UIAChildWindow cmdlet Get-UIAWindow -pn calc | Get-UIAChildWindow; # using recursive search for a control of window type (in practice, the same as using the Get-UIAChildWindow cmdlet) Get-UIAWindow -pn calc | Get-UIAControl -ControlType Window;
These samples worked well for us until there were three or more windows open (the main form, the child form and a message box, for example. Another case is the main form and two child forms) or the main form is so complex that consists of two or more forms (dockable parts or a window inside an MMC application).
In such cases, the search for a certain window led to complicated code, especially when forms had the same captions.
Time changed, let’s review new ways of getting a certain window:
# the topmost window (there are no changes with the previous behavior) Get-UIAWindow -pn calc; # all windows of the process(es): Get-UIAWindow -pn calc -Recurse; # all windows with the phrase 'calc' in caption Get-UIAWindow -pn calc -Name *calc*; # all windows with the word 'about' in caption (in fact, it's only the child window) Get-UIAWindow -pn calc -Name *about*; # all windows with ClassName like 'frame' (the main window has Classname == 'CalcFrame') Get-UIAWindow -pn calc -Class *frame*; # all windows with ClassName == '#32770' (the child window has such a standard class name) Get-UIAWindow -pn calc -Class '#32770';
As can be easily seen, one call of the Get-UIAWindow cmdlet could substitute an old-days function of getting the right window.
The only problem in recursive search for windows is the time it could take: if forms are full of controls, the search will relatively slow.
Just to drop a couple of words about parameterless search. How many words could be used describing parameterless search?
Let’s dive into samples:
# the classic parameterless search for a control Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name  | Invoke-UIAButtonClick; Get-UIAText 123;
# here we search for a control that has handle Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name  | Invoke-UIAButtonClick; Get-UIAText 123 -Win32;
# using wildcards in parameterless search (-Win32 only) Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name  | Invoke-UIAButtonClick; Get-UIAText 12* -Win32;
All three samples return the same: two labels (texts). However, you should understand that
- the first sample (i.e., Get-UIAText 123) works via MS UI Automation. This means that there is no use of wildcards. The query is (ControlType.Text AND (Name == ‘123’ OR AutomationId == ‘123’ OR ClassName == ‘123’ OR ValuePattern.Value == ‘123’)).
- the second and the third samples work via Win32 API (SendMessage) and check for the value given every AutomationElement with handle of given type
The only disadvantage of this syntax is a habit to supply all names with asterisks:
# MS UI Automation does not like asterisks: Get-UIAText 12*; # use the -Win32 parameter if applicable Get-UIAText 12* -Win32; # or the exact name, automation id, class name or value of a control Get-UIAText 123;
In simple situation this syntax helps make your code even simpler:
Start-Process calc -PassThru | Get-UIAWindow | Get-UIAMenuItem view | Invoke-UIAMenuItemExpand | Get-UIAMenuItem worksheets | Move-UIACursor -X 10 -Y 10 | Get-UIAMenuItem mortgage | Invoke-UIAMenuItemClick;