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;
As you could notice, versions 0.8.3, 0.8.4 and 0.8.5 of the UIAutomation module took a few steps to be simpler and more friendly to the user. We carried out the following improvements to the module:
- added a Win32 click to the InvokePattern cmdlets (i.e., Invoke-UIAButtonClick, Invoke-UIAMenuItemClick, etc) in the case when pattern failed
- added the -Value parameter to Get-UIA[ControlType] cmdlets (i.e., Get-UIAEdit, etc)
- added the parameterless search like Get-UIAButton Next
- and we are working on an improvement to Set-UIAControlText and Set-UIAControlKeys cmdlets
Today’s post sheds light on the brand-new -Value parameter. Many controls support ValuePattern. The preceding link and this one give us the following definitions: “Represents a control that has an intrinsic value that does not span a range and can be represented as a string. This string may or may not be editable depending on the control and its settings.” “Allows clients to get or set a value on controls that do not support a range of values. For example, a date time picker.”
In practice, ValuePattern’s value is a string in a text field. Typically, it’s not wise to search for a text box by the value that is inside. It may be useful in certain situations (i.e., text boxes that are hard to recognize, for example, those that have auto-generated ids in AutomationId. And, in such situations, search for a control by a value in the field could help).
Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name  | Invoke-UIAButtonClick; Get-UIAText -Value 123;
A better example is Computer Management -> Disk Management: while names of drives’ squares say the number of device and partition, values contain descriptive information:
Get-UIAWindow -Name *comp*manag* | Get-UIACustom -Value *unallocated*;
Where else the -Value parameter can be used? Accordingly to the suggested controls to patterns mapping, ValuePattern is useful when automating links.
For example, a link in an event’s help page in Event viewer:
Get-UIAWindow -n *event*event* | Get-UIAHyperlink -Value *event*log*online*;
What’s more, link’s href is available even it’s invisible:
Get-UIAWindow -n *control*pattern*mapping* | Get-UIAHyperlink -Value '*#control_mapping_clients*' | Read-UIAControlName;
Finally, the best area of applicability of the -Value parameter is grids and other complex controls.
Task: demonstrate how to write in text into a text box field.
Requirements: use UI Automation pattern or Win32.
Solution: the typical code is as follows:
Get-UIAWindow -Name $formTitle | ` Get-UIAEdit -AutomationId UsernameBox | ` Set-UIAEditText -Text "text";
Despite the name, the Set-UIAEditText cmdlet uses ValuePattern. This is because that Set-UIAEditText as well as any Set-UIA[ControlType]Text cmdlet is an alias of the Invoke-UIAValuePatternSet cmdlet.
the same story with the Set-UIATextBoxText cmdlet, which is the alias for Set-UIAEditText.
Not every time controls that are supposed to support ValuePattern really support it. This may depend on the developer’s code or on a control’s state. For example, a combo box supports ValuePattern if it has a field to write text in.
As promised, accessing such controls programmatically should raise the ModifiedChanged event.
Sometimes, the ValuePattern can be inaccessible. Due to many reasons, it happens, though rarely. Under these circumstances, you may use the Set-UIAControlText cmdlet, the pure Win32 text setter.
Get-UIAWindow -Name $formTitle | ` Get-UIAEdit -AutomationId UsernameBox | ` Set-UIAControlText -Text "text";
Notice, however, that it works slightly differently: it puts text before the text that is already in the text field. What means that you need first to clean it up, the control, before putting a new text in.