Daily automation: crawling here and there


Sometimes, queries are not the best way to navigate along the Automation tree. Why? Get-UIA[ControlType] cmdlets return only one control. The Search-UIAControl cmdlet returns all controls that match, but it needs previously to run around all the Automation tree that may be too long in certain applications.

What if your only need is to get a few controls situated at the same level of the Automation tree? My choice is to get one and navigate to the next sibling. Theoretically, the control that a Get- cmdlet returned is the first sibling, i.e. navigating to the previous sibling is not demanded at the same extent as to the next sibling. Though, no one guarantees that the control you’ve been given is the first child of its parent.

Thus, several cmdlets are here to help you turning left or right when necessary.

Task: demonstrate how to navigate along the Automation tree.

Requirements: figure out which cmdlets are helpful regarding navigation.

Solution: the first example shows the mistake almost everyone makes. “It should be here, under this, why your cmdlets don’t work?” I hear similar questions regularly. Don’t be confused with your results: the control of your interest might be not here. Where? Anywhere? No, just one or more levels below the hierarchy. Let’s run the following code (all the pieces of code are based on the assumption that the UIAutomation module is loaded, of course):

Start-Process calc -PassThru | Get-UIAWindow | Get-UIAControlChildren | %{ Write-Host $_.Current.ControlType.ProgrammaticName $_.Current.Name $_.Current.AutomationId; }

My Calculator returns three controls. Haven’t you been expecting that the Get-UIAControlChildren cmdlet would return all the buttons numbered from 0 till 9? Nay, they are level or levels below. Now, we’ll get all the descendants:

Start-Process calc -PassThru | Get-UIAWindow | Get-UIAControlDescendants | %{ Write-Host $_.Current.ControlType.ProgrammaticName $_.Current.Name $_.Current.AutomationId; }

This code returns tens and tens of controls. I even calculated to announce that this time it returned 73 controls:

(Start-Process calc -PassThru | Get-UIAWindow | Get-UIAControlDescendants).Count

The Search-UIAControl returns 75 objects (possibly, objects with empty name and automation id are being calculated in various ways), but somewhat slower: the cmdlet walks the Automation tree what requires much more process-to-process calls.

(Start-Process calc -PassThru | Get-UIAWindow | Search-UIAControl -Name *).Count

So where are the buttons? Just refine the search at first:

(Start-Process calc -PassThru | Get-UIAWindow | Get-UIAControlDescendants -ControlType Button).Count

Calculator in the Scientific mode returned 53 buttons, both buttons with numbers and signs and control buttons like ‘Minimize the window’.
Okay, let’s repeat the question: where our buttons are? Which control might be their parent? The main window? A pane under the main window?

(Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 1 | Get-UIAcontrolParent).Current.ControlType.ProgrammaticName

Right, a pane. The full list of ancestors for this button is provided by the Get-UIAControlAncestors cmdlet:

Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 1 | Get-UIAControlAncestors | %{ Write-Host $_.Current.ControlType.ProgrammaticName $_.Current.Name $_.Current.AutomationId; }

The main window contains a pane, it in turn contains another pane, which button are placed on.
It’s time to navigate horizontally:

Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 1 | Get-UIAControlNextSibling

Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 1 | Get-UIAControlNextSibling| Get-UIAControlNextSibling

Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 1 | Get-UIAControlNextSibling| Get-UIAControlPreviousSibling

Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 1 | Get-UIAControlPreviousSibling

The first line of code returns the button 0, the second – MR, the third – (any doubts?) 1, the fourth – 4.

Eventually, we are going to know which of buttons is the first. To achieve this goal, we’ll get a button, get its parent, and get the first child:

Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 1 | Get-UIAControlParent | Get-UIAControlFirstChild

Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 1 | Get-UIAControlParent | Get-UIAControlLastChild

The first button is MC, the last (don’t you think that the Get-UIAControlLastChild is the less usable cmdlet if even me avoiding to use it?) – ‘ten in the X degree’.

After the navigating crash course has been conpleted, you are able to sail to wherever your controls are!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: