# encoding: ascii
# api: powershell
# title: UIAutomation
# description: This is a further preview of what you can do with System.Windows.UIAutomation — The new WASP module is coming…
# version: 1.3
# type: module
# author: Joel Bennett
# license: CC0
# function: New-UIAElement
# x-poshcode-id: 990
# x-derived-from-id: 1227
# x-archived: 2015-11-24T02:09:55
# x-published: 2009-04-01T22:31:00
#
#
# #
# Select-Window Notepad | Remove-Window -passthru #
# ## And later ... #
# Select-Window Notepad | Select-ChildWindow | Send-Keys "%N" #
# ## OR ## #
# Select-Window Notepad | Select-ChildWindow | #
# Select-Control -title "Do&n't Save" -recurse | Send-Click #
# #
# #
# PS notepad | Select-Window | Select-ChildWindow | %{ New-Object Huddled.Wasp.Window $_ } #
# #
# cp C:\Users\Joel\Projects\PowerShell\Wasp\trunk\WASP\bin\Debug\Wasp.dll .\Modules\WASP\ #
# Import-Module WASP
# function formatter { END {
# $input | Format-Table @{l="Text";e={$_.Text.SubString(0,25)}}, ClassName, FrameworkId -Auto
# }}
# Add-Type -AssemblyName UIAutomationClient
# Add-Type -AssemblyName UIAutomationTypes
[Reflection.Assembly]::Load("UIAutomationClient, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
[Reflection.Assembly]::Load("UIAutomationTypes, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
$SWA = "System.Windows.Automation"
Import-Module Accelerators
Add-Accelerator AutoElement "$SWA.AutomationElement" -EA SilentlyContinue
$UIAFunctions = @{}
# Add-Accelerator InvokePattern "$SWA.InvokePattern" -EA SilentlyContinue
# Add-Accelerator ExpandPattern "$SWA.ExpandCollapsePattern" -EA SilentlyContinue
# Add-Accelerator WindowPattern "$SWA.WindowPattern" -EA SilentlyContinue
# Add-Accelerator TransformPattern "$SWA.TransformPattern" -EA SilentlyContinue
# Add-Accelerator ValuePattern "$SWA.ValuePattern" -EA SilentlyContinue
# Add-Accelerator TextPattern "$SWA.TextPattern" -EA SilentlyContinue
$Patterns = [Reflection.Assembly]::GetAssembly([System.Windows.Automation.BasePattern]).GetTypes() |
Where {$_.BaseType -like "System.Windows.Automation.BasePattern"}
## TODO: Write Get-SupportedPatterns or rather ...
## Get-SupportedFunctions (to return the names of the functions for the supported patterns)
## TODO: Support all the "Properties" too
## TODO: Figure out why Notepad doesn't support SetValue
## TODO: Figure out where the menus support went
ForEach($pattern in $Patterns){
$FullName = $pattern.FullName
$pattern.GetMethods() |
Where { $_.DeclaringType -eq $_.ReflectedType -and !$_.IsSpecialName } |
ForEach {
$Name = $($_.Name -replace 'Pattern`$')
$Func1 = "Function:Invoke-$($Name)"
$Func = "Function:Global:Invoke-$($Name)"
if (test-path $Func1) { remove-item $Func1 }
New-Item $Func -value "
Param( $( [string]::Join( ", ", @($_.GetParameters() | % { "[$($_.ParameterType.FullName)]`$$($_.Name)" })) ) )
Process {
trap { Write-Warning `"`$(`$_)`"; continue }
`$pattern = `$_.GetCurrentPattern([$FullName]::Pattern)
if(`$pattern) {
`$Pattern.GetType().InvokeMember('$($_.name)','Public,Instance,InvokeMethod', `$null, `$pattern, `$PSBoundParameters.Values)
}
}"
}
$pattern.GetProperties() |
Where { $_.DeclaringType -eq $_.ReflectedType -and $_.Name -notmatch "Cached|Current"} |
ForEach {
$Name = $($_.Name -replace 'Pattern`$')
$Func1 = "Function:Get-$($Name)"
$Func = "Function:Global:Get-$($Name)"
if (test-path $Func1) { remove-item $Func1 }
New-Item $Func -value "Process {
trap { Write-Warning `"$FullName `$_`"; continue }
`$pattern = `$_.GetCurrentPattern([$FullName]::Pattern)
if(`$pattern) {
`$pattern.'$($_.name)'
}
}"
}
}
Add-Accelerator Condition "$SWA.Condition" -EA SilentlyContinue
Add-Accelerator AndCondition "$SWA.AndCondition" -EA SilentlyContinue
Add-Accelerator OrCondition "$SWA.OrCondition" -EA SilentlyContinue
Add-Accelerator NotCondition "$SWA.NotCondition" -EA SilentlyContinue
Add-Accelerator PropertyCondition "$SWA.PropertyCondition" -EA SilentlyContinue
Add-Accelerator AutoElementIds "$SWA.AutomationElementIdentifiers" -EA SilentlyContinue
Add-Accelerator TransformIds "$SWA.TransformPatternIdentifiers" -EA SilentlyContinue
$FalseCondition = [Condition]::FalseCondition
$TrueCondition = [Condition]::TrueCondition
Add-Type -AssemblyName System.Windows.Forms
Add-Accelerator SendKeys System.Windows.Forms.SendKeys -EA SilentlyContinue
function New-UIAElement {
[CmdletBinding()]
PARAM(
[Parameter(ValueFromPipeline=$true)]
[AutoElement]$Element
)
PROCESS {
$Element |
Add-Member -Name Text -Type ScriptProperty -PassThru -Value {
$this.GetCurrentPropertyValue([AutoElementIds]::NameProperty)
} | Add-Member -Name ClassName -Type ScriptProperty -Passthru -Value {
$this.GetCurrentPropertyValue([AutoElementIds]::ClassNameProperty)
} | Add-Member -Name FrameworkId -Type ScriptProperty -Passthru -Value {
$this.GetCurrentPropertyValue([AutoElementIds]::FrameworkIdProperty)
} | Add-Member -Name ProcessId -Type ScriptProperty -Passthru -Value {
$this.GetCurrentPropertyValue([AutoElementIds]::ProcessIdProperty)
} | Add-Member -Name ControlType -Type ScriptProperty -Passthru -Value {
$this.GetCurrentPropertyValue([AutoElementIds]::LocalizedControlTypeProperty)
}
# $e =
# ForEach($method in $UIAFunctions.GetEnumerator()) {
# $e = & $method.Value $e
# }
# $e
}
}
function Select-Window {
[CmdletBinding()]
PARAM(
[Parameter()]
[Alias("Name")]
[string]$Text="*"
,
[Parameter()]
[string]$ClassName="*"
,
[Parameter()]
[string]$ControlType="*"
,
[Parameter()]
[switch]$Recurse
,
[Parameter(ValueFromPipeline=$true)]
[AutoElement]$Parent = [AutoElement]::RootElement
)
PROCESS {
if($Recurse) {
$Parent.FindAll( "Descendants", $TrueCondition ) | New-UIAElement |
Where-Object {
($_.ClassName -like $ClassName) -AND
($_.Text -like $Text) -AND
($_.ControlType -like $ControlType)
}
} else {
$Parent.FindAll( "Children", $TrueCondition ) | New-UIAElement |
Where-Object {
($_.ClassName -like $ClassName) -AND
($_.Text -like $Text) -AND
($_.ControlType -like $ControlType)
}
}
}
}
function formatter { END {
$input | Format-Table @{l="Text";e={$_.Text.SubString(0,25)}}, ClassName, FrameworkId -Auto
}}
function Invoke-Element {
[CmdletBinding()]
PARAM(
[Parameter(ValueFromPipeline=$true)]
[AutoElement]$Target
)
PROCESS {
$Target.GetCurrentPattern([InvokePattern]::Pattern).Invoke()
}
}
function Set-ElementText {
[CmdletBinding()]
PARAM(
[Parameter()]
[string]$Text
,
[Parameter(ValueFromPipeline=$true)]
[AutoElement]$Target
)
PROCESS {
$Target.SetFocus();
$textPattern = $valuePattern = $null
try {
$textPattern = $Target.GetCurrentPattern([TextPattern]::Pattern)
Write-Host "textPattern:`n$($textPattern | gm)"
} catch { }
try {
$valuePattern = $Target.GetCurrentPattern([ValuePattern]::Pattern)
Write-Host "valuePattern:`n$($valuePattern | gm)"
} catch { }
$Target.SetFocus();
if($valuePattern) {
$valuePattern.SetValue( $Text )
}
if($textPattern) {
[SendKeys]::SendWait("^{HOME}");
[SendKeys]::SendWait("^+{END}");
[SendKeys]::SendWait("{DEL}");
[SendKeys]::SendWait( $Text )
}
}
}