~UI Automationで画面操作捕捉!その4~ UI Automation with PowerShell 奮戦記 7日目

UI Automation*1で遊ぼう!

UI Automation の画面操作の捕捉機能を使用した画面ハードコピーの自動化に挑戦しています。Windowsの標準実装のみ、PowerShellのみで動作させることを目指しています。

UI Automationでの画面操作の捕捉をPowerShellで出来るようにEventタイプを.Net Framworkで実装しました。
実装した開発ライブラリ、共通で使用するスクリプトについては以下を確認してくださいね。
https://amon52280sub.hateblo.jp/entry/2019/01/23/032420


前回の操作パターンでの問題はイベント追加実装で解決。
開発ライブラリの$uia.SetEvent($ev[0])の中でプロパティ変更のイベント登録を実行しています。
PowerShell Version3(管理者権限)で実行してみる。

# UI Automation 共通ファンクションを組み込む
. .\UIA.ps1

# 初期化
$global:uia = UIA_Init

# Timer イベント捕捉
$global:timer = New-Object System.Timers.Timer
$timer.Interval = 100
$timer.Enabled = $false
Register-ObjectEvent -InputObject $timer -EventName Elapsed -Action {
  try {
  $name = $ev[0].current.name
  $controltype = $ev[0].current.localizedcontroltype
  $classname = $ev[0].current.classname
  $eventid = $ev[1].EventId.ProgrammaticName
  Write-Host $(UIA_OutPut -element $ev[0] -event $ev[1] -mode Event | Out-String)
  $timer.Enabled = $false
  } catch {
    Write-Host $_
  }
} | Out-Null

# UI AUtomation イベント捕捉
Register-ObjectEvent -InputObject $uia -EventName UIChange -Action {
  try {
  $timer.Enabled = $false

  $global:ev = $args
  $name = $ev[0].current.name
  $controltype = $ev[0].current.localizedcontroltype
  $classname = $ev[0].current.classname
  $eventid = $ev[1].EventId.ProgrammaticName

  if ($name -match "powershell") {return}
  switch ($eventid) {
    ("AutomationElementIdentifiers.AutomationFocusChangedEvent") {
      $uia.SetEvent($ev[0])
      $timer.Interval = 1000
      $timer.Enabled = $true
    }
    ("AutomationElementIdentifiers.AutomationPropertyChangedEvent") {
      $uia.SetEvent($ev[0])
      $timer.Interval = 1000
      $timer.Enabled = $true
    }
    ("WindowPatternIdentifiers.WindowOpenedProperty"){
      Write-Host $(UIA_OutPut -element $ev[0] -event $ev[1] -mode Event | Out-String)
      $timer.Interval = 1000
      $timer.Enabled = $false
    }
    ("WindowPatternIdentifiers.WindowClosedProperty"){
      $timer.Interval = 1000
      $timer.Enabled = $false
    }  
    default {
      Write-Host $(UIA_OutPut -element $ev[0] -event $ev[1] -mode Event |Out-String)
      $timer.Interval = 1000
      $timer.Enabled = $false
    }
  }
  } catch {
    Write-Host $_
  }  
} | Out-Null

# イベントスタート
$uia.StartEvent()

f:id:amon52280:20181215200937p:plainf:id:amon52280:20181215200940p:plainf:id:amon52280:20181215200944p:plain
フォルダーオプションを操作してみる

実行結果

ControlType : コンボ ボックス
ClassName   : ComboBox
EventID     : AutomationElementIdentifiers.AutomationFocusChangedEvent
Property    :
Name        : エクスプローラーで開く:


ControlType : チェック ボックス
ClassName   : Button
EventID     : AutomationElementIdentifiers.AutomationFocusChangedEvent
Property    :
Name        : 最近使ったファイルをクイック アクセスに表示する


ControlType : チェック ボックス
ClassName   : Button
EventID     : AutomationElementIdentifiers.AutomationPropertyChangedEvent
Property    : TogglePatternIdentifiers.ToggleStateProperty
Name        : 最近使ったファイルをクイック アクセスに表示する

このパターンでも

f:id:amon52280:20190109204446p:plainf:id:amon52280:20190109204449p:plainf:id:amon52280:20190109204442p:plain
フォルダーオプションを操作してみる

実行結果

ControlType : ボタン
ClassName   : Button
EventID     : AutomationElementIdentifiers.AutomationFocusChangedEvent
Property    :
Name        : フォルダーに適用(L)


ControlType : ツリー項目
ClassName   :
EventID     : AutomationElementIdentifiers.AutomationFocusChangedEvent
Property    :
Name        : すべてのフォルダーを表示


ControlType : ツリー項目
ClassName   :
EventID     : AutomationElementIdentifiers.AutomationPropertyChangedEvent
Property    : AutomationElementIdentifiers.NameProperty
Name        : すべてのフォルダーを表示

操作を認識出来ていますね。

*1:ここでのUI AutomationはSystem.Windows.Automationのことです