◆ UIAutomation について改めておさらい
・ UIAutomation はアクセシビリティのための機能であるが、これを利用してRPA的な操作の自動化やUIテストなどに使うことができる。
・ブログラムがアクセシビリティを提供するためには規定のインターフェイスを実装している必要がある。
・ IUIAutomation が中心となるインターフェイスである。
・ IUIAutomation を実装したクラスとして、 CUIAutomation が用意されている。
・ CUIAutomation8 というものもあり、これはWindows8から登場した、より上位のクラスである。 CUIAutomation8 は IUIAutomation2 を実装している。
・ IUIAutomation2 は IUIAutomation を拡張したもので、メソッドが追加されている。
・ CUIAutomation のクラスIDは ff48dba4-60ef-4201-aa87-54103eef594e らしい。
・Windows7から、 UIAutomation がCOMで提供されるようになった。(当初はアンマネージC++のAPIも提供されていた)
・別のユーザが実行したプロセスにはアクセスできない。
・Win32のコントロールなどにアクセスするためには、 Oleacc.dll が必要なので、これを参照設定する。
・ UI要素を分析するツールとして「Accessibility Insights」が提供されている。
https://accessibilityinsights.io/
・「Spy++」はVisual Studioに付属している。ただし「C++コア機能」コンポーネントをインストールしないとインストールされない。
・下記フォルダにインストールされる。
\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools
・32bit版と64bit版の2つがある。(分析対象によって使い分ける?)
・32bit版は、Spy++本体(spyxx.exe)と、「mfc140u.dll」「sypxxhk.dll」の2つのdllファイルがあれば動作するように見える。(VSをインストールしていないPCに3ファイルをコピーしたら動いた。64は3ファイルだけではダメ。)
・目指すUI要素を取得するための大まかな手順は、
① CUIAutomation を New する。
この CUIAutomation は、各種操作を行うためのオブジェクトで、要素を検索して特定するメソッドなどを持っている。
② IUIAutomationElement 型の変数を宣言する。
最終的にこの変数に目的のUIコントロール要素を代入して使用することになる。
③ New した CUIAutomation オブジェクトの各種メソッドを使って目的のUIコントロール要素を特定する。
.ElementFromHandle を使えばウィンドウハンドルから特定することができる。
④ メソッドの戻り値として返ってきた目的のUI要素を②の変数に代入。
⑤ 取得したUI要素を操作するためには、別途、「コントロールパターン」というものを用意する必要がある。
コントロールパターンは、操作したいUIの種類によって異なる。
以下、代表的な例として、「ボタンを押す」の場合。
⑥ IUIAutomationInvokePattern 型の変数を宣言する。
UI要素は、「 .GetCurrentPattern() 」というメソッドを持っているので、④で得られたUI要素を、
UI要素.GetCurrentPattern(UIA_InvokePatternId)
として、その戻り値を⑥の変数に代入する。
⑦ こうして得られた⑥のメソッドとして、「 .Invoke 」を実行する。
・一般的には、取得したいUI要素についてあらかじめ情報があれば、
IUIAutomationElement :: FindFirst
で探すのが定石。(ウィンドウハンドルでウィンドウを特定し、そこから FindFirst で下の階層を辿っていく)
・ IUIAutomation :: GetRootElement で、ルート要素(つまりデスクトップ)を取得することができる。(ただしそこから孫・ひ孫・・・の検索をすることは推奨されていない。直下の子のみ検索することが推奨。)
・ウィンドウハンドルからUIオートメーション要素を取得するには
IUIAutomation :: ElementFromHandle
・画面座標から取得することもできる
IUIAutomation :: ElementFromPoint
・フォーカスされている要素を取得することもできるらしい
IUIAutomation :: GetFocusedElement
・UIオートメーションのプロパティは、直接変更することができない(読み取り専用)。だからコントロールパターンを使用することになる。
・目的のUI要素を取得する際に、「 UIA_NamePropertyId 」で探すのが定石?(実はNameぐらいしか特定できる要素がない?しかしNameはデスクトップ全体では同名のものが複数存在することは充分ありうる。)
・UI要素はツリー構造になっているが、目的のものだけに絞り込んだサブツリーを作り、そのサブツリーに対して操作する、ということもできる。
・UIオートメーションの基礎(下記が最新版らしい)
https://docs.microsoft.com/ja-jp/windows/win32/winauto/entry-uiauto-win32
・Qiita「インターネットエクスプローラの通知バーで名前を付けて保存をVBAでする」
https://qiita.com/callmekohei/items/487aefe1db0fd86cc7cf