Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

Using WPF UI Automation with PowerShell

, 20 Sep 2010
Rate this:
Please Sign up or sign in to vote.
I encountered a problem while trying to use WPF UI Automation with PowerShell - PowerShell reported incorrect type for automation elements

Consider the following PowerShell script:

 
[void] [Reflection.Assembly]::Load('UIAutomationClient, ' +
    'Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35')
[void] [Reflection.Assembly]::Load('UIAutomationTypes, ' +
    'Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35')

$root = [Windows.Automation.AutomationElement]::RootElement
 
$condition = New-Object Windows.Automation.PropertyCondition( `
    [Windows.Automation.AutomationElement]::NameProperty, `
    'start')

$startButton = $root.FindFirst( `
    [Windows.Automation.TreeScope]::Descendants, $condition)
 
$startButton.Current.Name
$startButton.Current.ControlType.ProgrammaticName
 

It uses WPF UI automation to get the reference to the Windows XP Start button. But the output is unexpected:

 
start
ControlType.Pane
 

PowerShell reports the Start button control type as Pane. Here is the equivalent (at least I think so) C# console application:

 
using System;
using System.Windows.Automation;
namespace UIAutTest
{
    class Program
    {
        static void Main(string[] args)
        {
            AutomationElement root = AutomationElement.RootElement;
            AutomationElement startButton = root.FindFirst(TreeScope.Descendants,
                new PropertyCondition(AutomationElement.NameProperty, "start"));
            Console.WriteLine(startButton.Current.Name);
            Console.WriteLine(startButton.Current.ControlType.ProgrammaticName);
        }
    }
}
 

This time the output is:

 
start
ControlType.Button
 

So, what is the difference? When I first encountered this, I posted a question here[^] and here[^], but never got a response. On further research, I found this[^] thread on MSDN forums. The problem seemed similar to mine and in his reply Bruce Payette states two problems with the starting script. The first is that UI Automation API works only from STA threads and PowerShell always runs scripts MTA. The workaround for this is to run PowerShell with the -sta switch or to run scripts from within the PowerShell 'Integrated Scripting Environment' (ISE) which defaults (I believe) to STA.

 

The other issue was a problem 'with how PowerShell handles value types' and the demonstrated solution was to insert some inline C# code in the script to get the UIAutomation root element. For the script in question the root element was an instance of Notepad created in the script so the example didn't work for me because I needed a reference to AutomationElement.RootElement (the current desktop) and I had to create my own. here is the final script:

 
[void] [Reflection.Assembly]::Load('UIAutomationClient, ' + 
    'Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35')
[void] [Reflection.Assembly]::Load('UIAutomationTypes, ' + 
    'Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35')
$source = @"
using System;
using System.Windows.Automation;
namespace UIAutTools
{
    public class Element
    {
        public static AutomationElement RootElement
        {
            get
            {
                return AutomationElement.RootElement;
            }
        }
    }
}
"@
Add-Type -TypeDefinition $source -ReferencedAssemblies( `
    "UIAutomationClient", "UIAutomationTypes")
$root = [UIAutTools.Element]::RootElement
$condition = New-Object Windows.Automation.PropertyCondition( `
    [Windows.Automation.AutomationElement]::NameProperty, `
    'start')
$startButton = $root.FindFirst( `
    [Windows.Automation.TreeScope]::Descendants, $condition)
$startButton.Current.Name
$startButton.Current.ControlType.ProgrammaticName
 

I created a small C# class with one static property to return AutomationElement.RootElement and used Add-Type to add it to the script. This time the output was:

 
start
ControlType.Button

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Uros Calakovic
Systems / Hardware Administrator
Bosnia And Herzegovina Bosnia And Herzegovina
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web04 | 2.8.140922.1 | Last Updated 20 Sep 2010
Article Copyright 2010 by Uros Calakovic
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid