-
-
Save xiongjia/6749035 to your computer and use it in GitHub Desktop.
| #REQUIRES -Version 3.0 | |
| # This is a simple sample for access the MS UIAutomation in PowerShell. | |
| # In this sample: | |
| # 1. Load the MS UIA via System.Reflection.Assembly | |
| # 2. Launch the AUT ( calc.exe ) | |
| # 3. Find the AutomationElement via the AUT Process Id | |
| # 4. Find buttons via 'ClassName' and 'Name' property | |
| # 5. Click the '1', '+', '1', '=' buttons. | |
| # At last, we will get '2' in the result of calc App. | |
| # Load MS UIAutomation assemblies | |
| Write-Host "Loading MS UIA assemblies" | |
| [void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationClient") | |
| [void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationTypes") | |
| [void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationProvider") | |
| [void][System.Reflection.Assembly]::LoadWithPartialName("UIAutomationClientsideProviders") | |
| # Register client side provider | |
| Write-Host "Register client-side provider" | |
| $client = [System.Reflection.Assembly]::LoadWithPartialName("UIAutomationClientsideProviders") | |
| [Windows.Automation.ClientSettings]::RegisterClientSideProviderAssembly($client.GetName()) | |
| # Launch the AUT ( calc.exe ) & sleep 10 seconds for wait the process start | |
| Write-Host "Launching the AUT" | |
| $autProc = Start-Process calc -PassThru | |
| Start-Sleep -s 10 | |
| # Find the calc Element via the process Id | |
| Write-Host "Searching the AUT Root element" | |
| $rootElement = [Windows.Automation.AutomationElement]::RootElement | |
| $condAUTProc = New-Object Windows.Automation.PropertyCondition([Windows.Automation.AutomationElement]::ProcessIdProperty, $autProc.Id) | |
| $autElement = $rootElement.FindFirst([Windows.Automation.TreeScope]::Children, $condAUTProc) | |
| # Find the buttons '1', '+', '=' | |
| Write-Host "Searching the button elements" | |
| $condBtn = New-Object Windows.Automation.PropertyCondition([Windows.Automation.AutomationElement]::ClassNameProperty, "Button") | |
| $condName = New-Object Windows.Automation.PropertyCondition([Windows.Automation.AutomationElement]::NameProperty, "1") | |
| $condTarget = New-Object Windows.Automation.AndCondition($condBtn, $condName) | |
| $btn1Element = $autElement.FindFirst([Windows.Automation.TreeScope]::Descendants, $condTarget) | |
| $condName = New-Object Windows.Automation.PropertyCondition([Windows.Automation.AutomationElement]::NameProperty, "+") | |
| $condTarget = New-Object Windows.Automation.AndCondition($condBtn, $condName) | |
| $btnPlusElement = $autElement.FindFirst([Windows.Automation.TreeScope]::Descendants, $condTarget) | |
| $condName = New-Object Windows.Automation.PropertyCondition([Windows.Automation.AutomationElement]::NameProperty, "=") | |
| $condTarget = New-Object Windows.Automation.AndCondition($condBtn, $condName) | |
| $btnEqualElement = $autElement.FindFirst([Windows.Automation.TreeScope]::Descendants, $condTarget) | |
| # Click the buttons | |
| Write-Host "Clicking the buttons" | |
| $btn1Element.GetCurrentPattern([Windows.Automation.InvokePattern]::Pattern).Invoke() | |
| Start-Sleep -s 1 | |
| $btnPlusElement.GetCurrentPattern([Windows.Automation.InvokePattern]::Pattern).Invoke() | |
| Start-Sleep -s 1 | |
| $btn1Element.GetCurrentPattern([Windows.Automation.InvokePattern]::Pattern).Invoke() | |
| Start-Sleep -s 1 | |
| $btnEqualElement.GetCurrentPattern([Windows.Automation.InvokePattern]::Pattern).Invoke() | |
| Start-Sleep -s 1 | |
| Write-Host "Finished. Please check the results on the AUT." |
Hi @johndonnelly,
I just came across the same gist. Using UIA Verify http://uiautomationverify.codeplex.com/releases/view/11366 I was able to find out that the button names are "Add" and "Equals" respectively (Windows 7). Changing lines 44.48 to the correct names made it work:
`$condName = New-Object Windows.Automation.PropertyCondition([Windows.Automation.AutomationElement]::NameProperty, "Add")
$condName = New-Object Windows.Automation.PropertyCondition([Windows.Automation.AutomationElement]::NameProperty, "Equals")`
Script is working fine in debug mode. But getting this error when I try to call ps1 from bat script:
Exception calling "RegisterClientSideProviderAssembly" with "1" argument(s):
"Object reference not set to an instance of an object."
At C:\Users\Public\Desktop\Untitled.ps1:6 char:2
+ [Windows.Automation.ClientSettings]::RegisterClientSideProviderAssem ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NullReferenceException
Can anyone help..
@smartaquarius10 That's very unusual bug, - looks like when calling RegisterClientSideProviderAssembly from powershell.exe, first call fails with exception and all subsequent calls will be successful! Here is a workaround:
try
{
# WORKAROUND: There is a weird bug: first call fails ...
[Windows.Automation.ClientSettings]::RegisterClientSideProviderAssembly([UIAutomationClientsideProviders.UIAutomationClientSideProviders].Assembly.GetName())
}
catch {}
# ... second call succeeds:
[Windows.Automation.ClientSettings]::RegisterClientSideProviderAssembly([UIAutomationClientsideProviders.UIAutomationClientSideProviders].Assembly.GetName())
after this script works fine.
Nice script but I get "You cannot call a method on a null-valued expression." on line 56 and 60. It seems the + and the = button element objects aren't created?