PoshCode Logo PowerShell Code Repository

sample format file by shakila 3 weeks ago (modification of post by shakila view diff)
diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/3191"></script>download | new post

I really am still working on this replacement for the WASP module ;-)

This version fixes some problems with PowerShell 2 vs PowerShell 3 changes (it works in both now).

  1. ## UI Automation v 1.8 -- REQUIRES the Reflection module (current version: http://poshcode.org/3174 )
  2. ##
  3. # WASP 2.0 is getting closer, but this is still just a preview:
  4. # -- a lot of the commands have weird names still because they're being generated ignorantly
  5. # -- eg: Invoke-Toggle.Toggle and  Invoke-Invoke.Invoke
  6.  
  7. # v 1.7 - Fixes using multiple checks like: Select-UIElement Red: Edit
  8. # v 1.8 - Fixes .Net version problems: specifying CSharpVersion3 when in PowerShell 2
  9.  
  10. # IF your PowerShell is running in .Net 4
  11. if($PSVersionTable.CLRVersion -gt "4.0") {
  12.     $Language = "CSharp" # Version 4
  13.     Add-Type -AssemblyName "UIAutomationClient, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  14.     Add-Type -AssemblyName "UIAutomationTypes, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  15. } else {
  16.     # In PowerShell 2, we need to use the .Net 3 version
  17.     $Language = "CSharpVersion3"
  18.     Add-Type -AssemblyName "UIAutomationClient, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  19.     Add-Type -AssemblyName "UIAutomationTypes, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  20. }
  21.  
  22.  
  23. $SWA = "System.Windows.Automation"
  24. #  Add-Accelerator InvokePattern      "$SWA.InvokePattern"                -EA SilentlyContinue
  25. #  Add-Accelerator ExpandPattern      "$SWA.ExpandCollapsePattern"        -EA SilentlyContinue
  26. #  Add-Accelerator WindowPattern      "$SWA.WindowPattern"                -EA SilentlyContinue
  27. #  Add-Accelerator TransformPattern   "$SWA.TransformPattern"             -EA SilentlyContinue
  28. #  Add-Accelerator ValuePattern       "$SWA.ValuePattern"                 -EA SilentlyContinue
  29. #  Add-Accelerator TextPattern        "$SWA.TextPattern"                  -EA SilentlyContinue
  30.  
  31. # This is what requires the Reflection module:
  32. Add-Accelerator Automation         "$SWA.Automation"                   -EA SilentlyContinue
  33. Add-Accelerator AutomationElement  "$SWA.AutomationElement"            -EA SilentlyContinue
  34. Add-Accelerator TextRange          "$SWA.Text.TextPatternRange"        -EA SilentlyContinue
  35. #####  Conditions
  36. Add-Accelerator Condition          "$SWA.Condition"                    -EA SilentlyContinue
  37. Add-Accelerator AndCondition       "$SWA.AndCondition"                 -EA SilentlyContinue
  38. Add-Accelerator OrCondition        "$SWA.OrCondition"                  -EA SilentlyContinue
  39. Add-Accelerator NotCondition       "$SWA.NotCondition"                 -EA SilentlyContinue
  40. Add-Accelerator PropertyCondition  "$SWA.PropertyCondition"            -EA SilentlyContinue
  41. #####  IDentifiers
  42. Add-Accelerator AutoElementIds     "$SWA.AutomationElementIdentifiers" -EA SilentlyContinue
  43. Add-Accelerator TransformIds       "$SWA.TransformPatternIdentifiers"  -EA SilentlyContinue
  44.  
  45. ##### Patterns:
  46. $patterns = Get-Type -Assembly UIAutomationClient -Base System.Windows.Automation.BasePattern
  47.             #| Where { $_ -ne [System.Windows.Automation.InvokePattern] }
  48.  
  49.  
  50. Add-Type -Language $Language -ReferencedAssemblies UIAutomationClient, UIAutomationTypes -TypeDefinition @"
  51. using System;
  52. using System.ComponentModel;
  53. using System.Management.Automation;
  54. using System.Reflection;
  55. using System.Text.RegularExpressions;
  56. using System.Windows.Automation;
  57. using System.Runtime.InteropServices;
  58.  
  59.  
  60. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
  61. public class StaticFieldAttribute : ArgumentTransformationAttribute {
  62.   private Type _class;
  63.  
  64.   public override string ToString() {
  65.      return string.Format("[StaticField(OfClass='{0}')]", OfClass.FullName);
  66.   }
  67.  
  68.   public override Object Transform( EngineIntrinsics engineIntrinsics, Object inputData) {
  69.      if(inputData is string && !string.IsNullOrEmpty(inputData as string)) {
  70.         System.Reflection.FieldInfo field = _class.GetField(inputData as string, BindingFlags.Static | BindingFlags.Public);
  71.         if(field != null) {
  72.            return field.GetValue(null);
  73.         }
  74.      }
  75.      return inputData;
  76.   }
  77.  
  78.   public StaticFieldAttribute( Type ofClass ) {
  79.      OfClass = ofClass;
  80.   }
  81.  
  82.   public Type OfClass {
  83.      get { return _class; }
  84.      set { _class = value; }
  85.   }  
  86. }
  87.  
  88. public static class UIAutomationHelper {
  89.  
  90.   [DllImport ("user32.dll", CharSet = CharSet.Auto)]
  91.   static extern IntPtr FindWindow (string lpClassName, string lpWindowName);
  92.  
  93.   [DllImport ("user32.dll", CharSet = CharSet.Auto)]
  94.   static extern bool AttachThreadInput (int idAttach, int idAttachTo, bool fAttach);
  95.  
  96.   [DllImport ("user32.dll", CharSet = CharSet.Auto)]
  97.   static extern int GetWindowThreadProcessId (IntPtr hWnd, IntPtr lpdwProcessId);
  98.  
  99.   [DllImport ("user32.dll", CharSet = CharSet.Auto)]
  100.   static extern IntPtr SetForegroundWindow (IntPtr hWnd);
  101.  
  102.   public static AutomationElement RootElement {
  103.      get { return AutomationElement.RootElement; }
  104.   }
  105.  
  106.  
  107.   ///<synopsis>Using Win32 to set foreground window because AutomationElement.SetFocus() is unreliable</synopsis>
  108.   public static bool SetForeground(this AutomationElement element)
  109.   {
  110.      if(element == null) {
  111.         throw new ArgumentNullException("element");
  112.      }
  113.  
  114.      // Get handle to the element
  115.      IntPtr other = FindWindow (null, element.Current.Name);
  116.  
  117.      // // Get the Process ID for the element we are trying to
  118.      // // set as the foreground element
  119.      // int other_id = GetWindowThreadProcessId (other, IntPtr.Zero);
  120.      //
  121.      // // Get the Process ID for the current process
  122.      // int this_id = GetWindowThreadProcessId (Process.GetCurrentProcess().Handle, IntPtr.Zero);
  123.      //
  124.      // // Attach the current process's input to that of the
  125.      // // given element. We have to do this otherwise the
  126.      // // WM_SETFOCUS message will be ignored by the element.
  127.      // bool success = AttachThreadInput(this_id, other_id, true);
  128.  
  129.      // Make the Win32 call
  130.      IntPtr previous = SetForegroundWindow(other);
  131.  
  132.      return !IntPtr.Zero.Equals(previous);
  133.   }
  134. }
  135. "@
  136.            
  137. ## TODO: Write Get-SupportedPatterns or rather ...
  138. ## Get-SupportedFunctions (to return the names of the functions for the supported patterns)
  139. ## TODO: Support all the "Properties" too
  140. ## TODO: Figure out why Notepad doesn't support SetValue
  141. ## TODO: Figure out where the menus support went
  142. ForEach($pattern in $patterns){
  143.    $pattern | Add-Accelerator
  144.    $PatternFullName = $pattern.FullName
  145.    $PatternName = $Pattern.Name -Replace "Pattern","."
  146.    $newline = "`n`t`t"
  147.    
  148.    New-Item "Function:ConvertTo-$($Pattern.Name)" -Value "
  149.   param(
  150.      [Parameter(ValueFromPipeline=`$true)][Alias('Element','AutomationElement')][AutomationElement]`$InputObject
  151.   )
  152.   process {
  153.      trap {
  154.         if(`$_.Exception.Message -like '*Unsupported Pattern.*') {
  155.            Write-Error `"Cannot get ```"$($Pattern.Name)```" from that AutomationElement, `$(`$_)` You should try one of: `$(`$InputObject.GetSupportedPatterns()|%{```"'```" + (`$_.ProgrammaticName.Replace(```"PatternIdentifiers.Pattern```",```"```")) + ```"Pattern'```"})`"; continue;
  156.         }
  157.      }
  158.      Write-Output `$InputObject.GetCurrentPattern([$PatternFullName]::Pattern).Current
  159.   }"
  160.    
  161.    $pattern.GetMethods() |
  162.    Where { $_.DeclaringType -eq $_.ReflectedType -and !$_.IsSpecialName } |
  163.    ForEach {
  164.       $FunctionName = "Function:Invoke-$PatternName$($_.Name)"
  165.       $Position = 1
  166.      
  167.       if (test-path $FunctionName) { remove-item $FunctionName }
  168.       $Parameters = @("$newline[Parameter(ValueFromPipeline=`$true)]"+
  169.                       "$newline[Alias('Parent','Element','Root','AutomationElement')]"+
  170.                       "$newline[AutomationElement]`$InputObject"
  171.                       ) +
  172.                     @(
  173.                       "[Parameter()]$newline[Switch]`$Passthru"
  174.                      ) +
  175.                     @($_.GetParameters() | % { "[Parameter(Position=$($Position; $Position++))]$newline[$($_.ParameterType.FullName)]`$$($_.Name)" })
  176.       $Parameters = $Parameters -Join "$newline,$newline"
  177.       $ParameterValues = '$' + (@($_.GetParameters() | Select-Object -Expand Name ) -Join ', $')
  178.  
  179.       $definition = @"
  180.   param(
  181.      $Parameters
  182.   )
  183.   process {
  184.      ## trap { Write-Warning "`$(`$_)"; break }
  185.      `$pattern = `$InputObject.GetCurrentPattern([$PatternFullName]::Pattern)
  186.      if(`$pattern) {
  187.         `$Pattern.$($_.Name)($(if($ParameterValues.Length -gt 1){ $ParameterValues }))
  188.      }
  189.      if(`$passthru) {
  190.         `$InputObject
  191.      }
  192.   }
  193. "@
  194.      
  195.       trap {
  196.          Write-Warning $_
  197.          Write-Host $definition -fore cyan
  198.       }
  199.       New-Item $FunctionName -value $definition
  200.    }
  201.    
  202.    $pattern.GetProperties() |
  203.    Where { $_.DeclaringType -eq $_.ReflectedType -and $_.Name -notmatch "Cached|Current"} |
  204.    ForEach {
  205.       $FunctionName = "Function:Get-$PatternName$($_.Name)".Trim('.')
  206.       if (test-path $FunctionName) { remove-item $FunctionName }
  207.       New-Item $FunctionName -value "
  208.      param(
  209.         [Parameter(ValueFromPipeline=`$true)]
  210.         [AutomationElement]`$AutomationElement
  211.      )      
  212.      process {
  213.         trap { Write-Warning `"$PatternFullName `$_`"; continue }
  214.         `$pattern = `$AutomationElement.GetCurrentPattern([$PatternFullName]::Pattern)
  215.         if(`$pattern) {
  216.            `$pattern.'$($_.Name)'
  217.         }
  218.      }"
  219.    }
  220.    ## So far this seems to be restricted to Text (DocumentRange) elements
  221.    $pattern.GetFields() |
  222.    Where { $_.FieldType.Name -like "*TextAttribute"} |
  223.    ForEach {
  224.       $FunctionName = "Function:Get-Text$($_.Name -replace 'Attribute')"
  225.       if (test-path $FunctionName) { remove-item $FunctionName }
  226.       New-Item $FunctionName -value "
  227.      param(
  228.         [Parameter(ValueFromPipeline=`$true)]
  229.         [AutomationElement]`$AutomationElement
  230.      )
  231.      process {
  232.         trap { Write-Warning `"$PatternFullName `$_`"; continue }
  233.         `$AutomationElement.GetAttributeValue([$PatternFullName]::$($_.Name))
  234.      }"
  235.    }
  236.    
  237.    $pattern.GetFields() | Where { $_.FieldType -eq [System.Windows.Automation.AutomationEvent] } |
  238.    ForEach {
  239.       $Name = $_.Name -replace 'Event$'
  240.       $FunctionName = "Function:Register-$($PatternName.Trim('.'))$Name"
  241.       if (test-path $FunctionName) { remove-item $FunctionName }
  242.       New-Item $FunctionName -value "
  243.      param(
  244.         [Parameter(ValueFromPipeline=`$true)]
  245.         [AutomationElement]`$AutomationElement
  246.      ,
  247.         [System.Windows.Automation.TreeScope]`$TreeScope = 'Element'
  248.      ,
  249.         [ScriptBlock]`$EventHandler
  250.      )
  251.      process {
  252.         trap { Write-Warning `"$PatternFullName `$_`"; continue }
  253.         [Automation]::AddAutomationEventHandler( [$PatternFullName]::$Name, `$AutomationElement, `$TreeScope, `$EventHandler )
  254.      }"
  255.    }
  256. }
  257.  
  258. $FalseCondition = [Condition]::FalseCondition
  259. $TrueCondition  = [Condition]::TrueCondition
  260.  
  261. Add-Type -AssemblyName System.Windows.Forms
  262. Add-Accelerator SendKeys           System.Windows.Forms.SendKeys       -EA SilentlyContinue
  263.  
  264. $AutomationProperties = [system.windows.automation.automationelement+automationelementinformation].GetProperties()
  265.  
  266. Set-Alias Invoke-UIElement Invoke-Invoke.Invoke
  267.  
  268. function formatter  { END {
  269.    $input | Format-Table @{l="Text";e={$_.Text.SubString(0,25)}}, ClassName, FrameworkId -Auto
  270. }}
  271.  
  272. function Get-ClickablePoint {
  273. [CmdletBinding()]
  274. param(
  275.    [Parameter(ValueFromPipeline=$true)]
  276.    [Alias("Parent","Element","Root")]
  277.    [AutomationElement]$InputObject
  278. )
  279.    process {
  280.       $InputObject.GetClickablePoint()
  281.    }
  282. }
  283.  
  284. function Show-Window {
  285. [CmdletBinding()]
  286. param(
  287.    [Parameter(ValueFromPipeline=$true)]
  288.    [Alias("Parent","Element","Root")]
  289.    [AutomationElement]$InputObject
  290. ,
  291.    [Parameter()]
  292.    [Switch]$Passthru  
  293. )
  294.    process {
  295.       Set-UIFocus $InputObject
  296.       if($passthru) {
  297.          $InputObject
  298.       }        
  299.    }
  300. }
  301.  
  302. function Set-UIFocus {
  303. [CmdletBinding()]
  304. param(
  305.    [Parameter(ValueFromPipeline=$true)]
  306.    [Alias("Parent","Element","Root")]
  307.    [AutomationElement]$InputObject
  308. ,
  309.    [Parameter()]
  310.    [Switch]$Passthru  
  311. )
  312.    process {
  313.       try {
  314.          [UIAutomationHelper]::SetForeground( $InputObject )
  315.          $InputObject.SetFocus()
  316.       } catch {
  317.          Write-Verbose "SetFocus fail, trying SetForeground"
  318.       }
  319.       if($passthru) {
  320.          $InputObject
  321.       }        
  322.    }
  323. }
  324.  
  325. function Send-UIKeys {
  326. [CmdletBinding()]
  327. param(
  328.    [Parameter(Position=0)]
  329.    [string]$Keys
  330. ,
  331.    [Parameter(ValueFromPipeline=$true)]
  332.    [Alias("Parent","Element","Root")]
  333.    [AutomationElement]$InputObject
  334. ,
  335.    [Parameter()]
  336.    [Switch]$Passthru
  337. ,
  338.    [Parameter()]
  339.    [Switch]$Async
  340. )
  341.    process {
  342.       if(!$InputObject.Current.IsEnabled)
  343.       {
  344.          Write-Warning "The Control is not enabled!"
  345.       }
  346.       if(!$InputObject.Current.IsKeyboardFocusable)
  347.       {
  348.          Write-Warning "The Control is not focusable!"
  349.       }
  350.       Set-UIFocus $InputObject
  351.      
  352.       if($Async) {
  353.          [SendKeys]::Send( $Keys )
  354.       } else {
  355.          [SendKeys]::SendWait( $Keys )
  356.       }
  357.      
  358.       if($passthru) {
  359.          $InputObject
  360.       }      
  361.    }
  362. }
  363.  
  364. function Set-UIText {
  365. [CmdletBinding()]
  366. param(
  367.    [Parameter(Position=0)]
  368.    [string]$Text
  369. ,
  370.    [Parameter(ValueFromPipeline=$true)]
  371.    [Alias("Parent","Element","Root")]
  372.    [AutomationElement]$InputObject
  373. ,
  374.    [Parameter()]
  375.    [Switch]$Passthru  
  376. )
  377.    process {
  378.       if(!$InputObject.Current.IsEnabled)
  379.       {
  380.          Write-Warning "The Control is not enabled!"
  381.       }
  382.       if(!$InputObject.Current.IsKeyboardFocusable)
  383.       {
  384.          Write-Warning "The Control is not focusable!"
  385.       }
  386.      
  387.       $valuePattern = $null
  388.       if($InputObject.TryGetCurrentPattern([ValuePattern]::Pattern,[ref]$valuePattern)) {
  389.          Write-Verbose "Set via ValuePattern!"
  390.          $valuePattern.SetValue( $Text )
  391.       }
  392.       elseif($InputObject.Current.IsKeyboardFocusable)
  393.       {
  394.          Set-UIFocus $InputObject
  395.          [SendKeys]::SendWait("^{HOME}");
  396.          [SendKeys]::SendWait("^+{END}");
  397.          [SendKeys]::SendWait("{DEL}");
  398.          [SendKeys]::SendWait( $Text )
  399.       }
  400.       if($passthru) {
  401.          $InputObject
  402.       }      
  403.    }
  404. }
  405.  
  406. function Select-UIElement {
  407. [CmdletBinding(DefaultParameterSetName="FromParent")]
  408. PARAM (
  409.    [Parameter(ParameterSetName="FromWindowHandle", Position="0", Mandatory=$true)]
  410.    [Alias("MainWindowHandle","hWnd","Handle","Wh")]
  411.    [IntPtr[]]$WindowHandle=[IntPtr]::Zero
  412. ,
  413.    [Parameter(ParameterSetName="FromPoint", Position="0", Mandatory=$true)]
  414.    [System.Windows.Point[]]$Point
  415. ,
  416.    [Parameter(ParameterSetName="FromParent", ValueFromPipeline=$true, Position=100)]
  417.    [System.Windows.Automation.AutomationElement]$Parent = [UIAutomationHelper]::RootElement
  418. ,
  419.    [Parameter(ParameterSetName="FromParent", Position="0")]
  420.    [Alias("WindowName")]
  421.    [String[]]$Name
  422. ,
  423.    [Parameter(ParameterSetName="FromParent", Position="1")]
  424.    [Alias("Type","Ct")]
  425.    [System.Windows.Automation.ControlType]
  426.    [StaticField(([System.Windows.Automation.ControlType]))]$ControlType
  427. ,
  428.    [Parameter(ParameterSetName="FromParent")]
  429.    [Alias("UId")]
  430.    [String[]]$AutomationId
  431. ,
  432.    ## Removed "Id" alias to allow get-process | Select-Window pipeline to find just MainWindowHandle
  433.    [Parameter(ParameterSetName="FromParent", ValueFromPipelineByPropertyName=$true )]
  434.    [Alias("Id")]
  435.    [Int[]]$PID
  436. ,
  437.    [Parameter(ParameterSetName="FromParent")]
  438.    [Alias("Pn")]
  439.    [String[]]$ProcessName
  440. ,
  441.    [Parameter(ParameterSetName="FromParent")]
  442.    [Alias("Cn")]
  443.    [String[]]$ClassName
  444. ,
  445.    [switch]$Recurse
  446. ,
  447.    [switch]$Bare
  448. )
  449. process {
  450.  
  451.    Write-Debug "Parameters Found"
  452.    Write-Debug ($PSBoundParameters | Format-Table | Out-String)
  453.  
  454.    $search = "Children"
  455.    if($Recurse) { $search = "Descendants" }
  456.    
  457.    $condition = [System.Windows.Automation.Condition]::TrueCondition
  458.    
  459.    Write-Verbose $PSCmdlet.ParameterSetName
  460.    switch -regex ($PSCmdlet.ParameterSetName) {
  461.       "FromWindowHandle" {
  462.          Write-Verbose "Finding from Window Handle $HWnd"
  463.          $Element = $(
  464.             foreach($hWnd in $WindowHandle) {
  465.                [System.Windows.Automation.AutomationElement]::FromHandle( $hWnd )
  466.             }
  467.          )
  468.          continue
  469.       }
  470.       "FromPoint" {
  471.          Write-Verbose "Finding from Point $Point"
  472.          $Element = $(
  473.             foreach($pt in $Point) {
  474.                [System.Windows.Automation.AutomationElement]::FromPoint( $pt )
  475.             }
  476.          )
  477.          continue
  478.       }
  479.       "FromParent" {
  480.          Write-Verbose "Finding from Parent!"
  481.          ## [System.Windows.Automation.Condition[]]$conditions = [System.Windows.Automation.Condition]::TrueCondition
  482.          [ScriptBlock[]]$filters = @()
  483.          if($AutomationId) {
  484.             [System.Windows.Automation.Condition[]]$current = $(
  485.                foreach($aid in $AutomationId) {
  486.                   new-object System.Windows.Automation.PropertyCondition ([System.Windows.Automation.AutomationElement]::AutomationIdProperty), $aid
  487.                }
  488.             )
  489.             if($current.Length -gt 1) {
  490.                [System.Windows.Automation.Condition[]]$conditions += New-Object System.Windows.Automation.OrCondition $current
  491.             } elseif($current.Length -eq 1) {
  492.                [System.Windows.Automation.Condition[]]$conditions += $current[0]
  493.             }  
  494.          }
  495.          if($PID) {
  496.             [System.Windows.Automation.Condition[]]$current = $(
  497.                foreach($p in $PID) {
  498.                   new-object System.Windows.Automation.PropertyCondition ([System.Windows.Automation.AutomationElement]::ProcessIdProperty), $p
  499.                }
  500.             )
  501.             if($current.Length -gt 1) {
  502.                [System.Windows.Automation.Condition[]]$conditions += New-Object System.Windows.Automation.OrCondition $current
  503.             } elseif($current.Length -eq 1) {
  504.                [System.Windows.Automation.Condition[]]$conditions += $current[0]
  505.             }        
  506.          }
  507.          if($ProcessName) {
  508.             if($ProcessName -match "\?|\*|\[") {
  509.                [ScriptBlock[]]$filters += { $(foreach($p in $ProcessName){ (Get-Process -id $_.GetCurrentPropertyValue([System.Windows.Automation.AutomationElement]::ProcessIdProperty)).ProcessName -like $p }) -contains $true }
  510.             } else {
  511.                [System.Windows.Automation.Condition[]]$current = $(
  512.                   foreach($p in Get-Process -Name $ProcessName) {
  513.                      new-object System.Windows.Automation.PropertyCondition ([System.Windows.Automation.AutomationElement]::ProcessIdProperty), $p.id, "IgnoreCase"
  514.                   }
  515.                )
  516.                if($current.Length -gt 1) {
  517.                   [System.Windows.Automation.Condition[]]$conditions += New-Object System.Windows.Automation.OrCondition $current
  518.                } elseif($current.Length -eq 1) {
  519.                   [System.Windows.Automation.Condition[]]$conditions += $current[0]
  520.                }              
  521.             }
  522.          }
  523.          if($Name) {
  524.             Write-Verbose "Name: $Name"
  525.             if($Name -match "\?|\*|\[") {
  526.                [ScriptBlock[]]$filters += { $(foreach($n in $Name){ $_.GetCurrentPropertyValue([System.Windows.Automation.AutomationElement]::NameProperty) -like $n }) -contains $true }
  527.             } else {
  528.                [System.Windows.Automation.Condition[]]$current = $(
  529.                   foreach($n in $Name){
  530.                      new-object System.Windows.Automation.PropertyCondition ([System.Windows.Automation.AutomationElement]::NameProperty), $n, "IgnoreCase"
  531.                   }
  532.                )
  533.                if($current.Length -gt 1) {
  534.                   [System.Windows.Automation.Condition[]]$conditions += New-Object System.Windows.Automation.OrCondition $current
  535.                } elseif($current.Length -eq 1) {
  536.                   [System.Windows.Automation.Condition[]]$conditions += $current[0]
  537.                }  
  538.             }
  539.          }
  540.          if($ClassName) {
  541.             if($ClassName -match "\?|\*|\[") {
  542.                [ScriptBlock[]]$filters += { $(foreach($c in $ClassName){ $_.GetCurrentPropertyValue([System.Windows.Automation.AutomationElement]::ClassNameProperty) -like $c }) -contains $true }
  543.             } else {
  544.                [System.Windows.Automation.Condition[]]$current = $(
  545.                   foreach($c in $ClassName){
  546.                      new-object System.Windows.Automation.PropertyCondition ([System.Windows.Automation.AutomationElement]::ClassNameProperty), $c, "IgnoreCase"
  547.                   }
  548.                )
  549.                if($current.Length -gt 1) {
  550.                   [System.Windows.Automation.Condition[]]$conditions += New-Object System.Windows.Automation.OrCondition $current
  551.                } elseif($current.Length -eq 1) {
  552.                   [System.Windows.Automation.Condition[]]$conditions += $current[0]
  553.                }                  
  554.             }
  555.          }
  556.          if($ControlType) {
  557.             if($ControlType -match "\?|\*|\[") {
  558.                [ScriptBlock[]]$filters += { $(foreach($c in $ControlType){ $_.GetCurrentPropertyValue([System.Windows.Automation.AutomationElement]::ControlTypeProperty) -like $c }) -contains $true }
  559.             } else {
  560.                [System.Windows.Automation.Condition[]]$current = $(
  561.                   foreach($c in $ControlType){
  562.                      new-object System.Windows.Automation.PropertyCondition ([System.Windows.Automation.AutomationElement]::ControlTypeProperty), $c
  563.                   }
  564.                )
  565.                if($current.Length -gt 1) {
  566.                   [System.Windows.Automation.Condition[]]$conditions += New-Object System.Windows.Automation.OrCondition $current
  567.                } elseif($current.Length -eq 1) {
  568.                   [System.Windows.Automation.Condition[]]$conditions += $current[0]
  569.                }                  
  570.             }
  571.          }
  572.          
  573.          if($conditions.Length -gt 1) {
  574.             [System.Windows.Automation.Condition]$condition = New-Object System.Windows.Automation.AndCondition $conditions
  575.          } elseif($conditions) {
  576.             [System.Windows.Automation.Condition]$condition = $conditions[0]
  577.          } else {
  578.             [System.Windows.Automation.Condition]$condition = [System.Windows.Automation.Condition]::TrueCondition
  579.          }
  580.          
  581.          If($VerbosePreference -gt "SilentlyContinue") {
  582.          
  583.             function Write-Condition {
  584.                param([Parameter(ValueFromPipeline=$true)]$condition, $indent = 0)
  585.                process {
  586.                   Write-Debug ($Condition | fl *  | Out-String)              
  587.                   if($condition -is [System.Windows.Automation.AndCondition] -or $condition -is [System.Windows.Automation.OrCondition]) {
  588.                      Write-Verbose ((" "*$indent) + $Condition.GetType().Name )
  589.                      $condition.GetConditions().GetEnumerator() | Write-Condition -Indent ($Indent+4)
  590.                   } elseif($condition -is [System.Windows.Automation.PropertyCondition]) {
  591.                      Write-Verbose ((" "*$indent) + $Condition.Property.ProgrammaticName + " = '" + $Condition.Value + "' (" + $Condition.Flags + ")")
  592.                   } else {
  593.                      Write-Verbose ((" "*$indent) + $Condition.GetType().Name + " where '" + $Condition.Value + "' (" + $Condition.Flags + ")")
  594.                   }
  595.                }
  596.             }
  597.          
  598.             Write-Verbose "CONDITIONS ============="
  599.             $global:LastCondition = $condition
  600.             foreach($c in $condition) {            
  601.                Write-Condition $c
  602.             }
  603.             Write-Verbose "============= CONDITIONS"
  604.          }
  605.          
  606.          if($filters.Count -gt 0) {
  607.             $Element = $Parent.FindAll( $search, $condition ) | Where-Object { $item = $_;  foreach($f in $filters) { $item = $item | Where $f }; $item }
  608.          } else {
  609.             $Element = $Parent.FindAll( $search, $condition )
  610.          }
  611.       }  
  612.    }
  613.    
  614.    Write-Verbose "Element Count: $(@($Element).Count)"
  615.    if($Element) {
  616.       foreach($el in $Element) {
  617.          if($Bare) {
  618.             Write-Output $el
  619.          } else {
  620.             $e = New-Object PSObject $el
  621.             foreach($prop in $e.GetSupportedProperties() | Sort ProgrammaticName)
  622.             {
  623.                ## TODO: make sure all these show up: [System.Windows.Automation.AutomationElement] | gm -sta -type Property
  624.                $propName = [System.Windows.Automation.Automation]::PropertyName($prop)
  625.                Add-Member -InputObject $e -Type ScriptProperty -Name $propName -Value ([ScriptBlock]::Create( "`$this.GetCurrentPropertyValue( [System.Windows.Automation.AutomationProperty]::LookupById( $($prop.Id) ))" )) -EA 0
  626.             }
  627.             foreach($patt in $e.GetSupportedPatterns()| Sort ProgrammaticName)
  628.             {
  629.                Add-Member -InputObject $e -Type ScriptProperty -Name ($patt.ProgrammaticName.Replace("PatternIdentifiers.Pattern","") + "Pattern") -Value ([ScriptBlock]::Create( "`$this.GetCurrentPattern( [System.Windows.Automation.AutomationPattern]::LookupById( '$($patt.Id)' ) )" )) -EA 0
  630.             }
  631.             Write-Output $e
  632.          }
  633.       }
  634.    }
  635. }
  636.  
  637. }
  638.  
  639.  
  640.  
  641. #   [Cmdlet(VerbsCommon.Add, "UIAHandler")]
  642. #   public class AddUIAHandlerCommand : PSCmdlet
  643. #   {
  644. #      private AutomationElement _parent = AutomationElement.RootElement;
  645. #      private AutomationEvent _event = WindowPattern.WindowOpenedEvent;
  646. #      private TreeScope _scope = TreeScope.Children;
  647. #
  648. #      [Parameter(ValueFromPipeline = true)]
  649. #      [Alias("Parent", "Element", "Root")]
  650. #      public AutomationElement InputObject { set { _parent = value; } get { return _parent; } }
  651. #
  652. #      [Parameter()]
  653. #      public AutomationEvent Event { set { _event = value; } get { return _event; } }
  654. #
  655. #      [Parameter()]
  656. #      public AutomationEventHandler ScriptBlock { set; get; }
  657. #
  658. #      [Parameter()]
  659. #      public SwitchParameter Passthru { set; get; }
  660. #
  661. #      [Parameter()]
  662. #      public TreeScope Scope { set { _scope = value; } get { return _scope; } }
  663. #
  664. #      protected override void ProcessRecord()
  665. #      {
  666. #         Automation.AddAutomationEventHandler(Event, InputObject, Scope, ScriptBlock);
  667. #
  668. #         if (Passthru.ToBool())
  669. #         {
  670. #            WriteObject(InputObject);
  671. #         }
  672. #
  673. #         base.ProcessRecord();
  674. #      }
  675. #   }
  676.  
  677. Export-ModuleMember -cmdlet * -Function * -Alias *

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me