UIAutomationのサンプル
昨日書いたもののソースを掲載。
クラス名はUIWindowでない方が良いかな。
$source = @" using System; using System.Windows.Automation; using System.Threading; public class UIWindow { private const int _moment = 100; private AutomationElement _ae; private AutomationProperty _ap = AutomationElement.AutomationIdProperty; public AutomationElement Element { get { return _ae; } } public AutomationProperty Property { get { return _ap; } set { _ap = value; } } public UIWindow() { _ae = AutomationElement.RootElement; } public UIWindow(string name) { _ae = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, name)); } public UIWindow(AutomationElement ae, AutomationProperty ap) { _ae = ae; _ap = ap; } public UIWindow FindFirst(TreeScope ts, string name) { AutomationElement ae = _ae.FindFirst(ts, new PropertyCondition(_ap, name)); return new UIWindow(ae, _ap); } public UIWindow FindFirst(string name) { return FindFirst(TreeScope.Descendants, name); } public UIWindow FindFirstHave(string className, string name) { UIWindow ret = null, sub = null; AutomationElementCollection aes = _ae.FindAll(TreeScope.Children, Condition.TrueCondition); foreach(AutomationElement ae in aes) { if (className.Equals(ae.GetCurrentPropertyValue(AutomationElement.ClassNameProperty))) { sub = new UIWindow(ae, _ap); sub = sub.FindFirstHave(className, name); if (sub != null) { if (className.Equals(sub.Element.GetCurrentPropertyValue(AutomationElement.ClassNameProperty))) { ret = sub; } else { ret = new UIWindow(ae, _ap); } break; } } else if (name.Equals(ae.GetCurrentPropertyValue(_ap))) { ret = new UIWindow(ae, _ap); break; } else { sub = new UIWindow(ae, _ap); sub = sub.FindFirstHave(className, name); if (sub != null && className.Equals(sub.Element.GetCurrentPropertyValue(AutomationElement.ClassNameProperty))) { ret = sub; break; } } } return ret; } public bool Invoke() { bool ret = false; InvokePattern iv = _ae.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern; if (iv != null) { try { iv.Invoke(); ret = true; } catch (ElementNotEnabledException e) { System.Diagnostics.Trace.Write(DateTime.Now); System.Diagnostics.Trace.WriteLine(e); ret = false; } } return ret; } public bool InvokeWaitEnable() { bool ret = WaitEnable(); ret = Invoke(); if (!ret) { // retry once Thread.Sleep(_moment * 10); ret = Invoke(); } return ret; } public bool WaitEnable() { bool ret = false; object val = _ae.GetCurrentPropertyValue(AutomationElement.IsEnabledProperty); if (val != null) { while (false.Equals(val)) { Thread.Sleep(_moment); val = _ae.GetCurrentPropertyValue(AutomationElement.IsEnabledProperty); } ret = true; } return ret; } public UIWindow WaitGet(bool child, string className, string name) { UIWindow ret = null; while (ret == null) { Thread.Sleep(_moment); if (child) { ret = FindFirstHave(className, name); } else { ret = FindFirst(name); } } return ret; } } "@ Add-Type -Language CSharp -TypeDefinition $source -ReferencedAssemblies ("UIAutomationClient", "UIAutomationTypes") #([AppDomain]::CurrentDomain).GetAssemblies() | Out-Gridview # メモ帳が起動している想定 # メモ帳を取得 $aec = New-Object UIWindow "無題 - メモ帳" # バージョンを表示してOK $aec.Property = [System.Windows.Automation.AutomationElement]::NameProperty $aeh = $aec.FindFirst("ヘルプ(H)") $aehe = $aeh.Element.GetCurrentPattern([System.Windows.Automation.ExpandCollapsePattern]::Pattern) $aehe.Expand() [System.Threading.Thread]::Sleep(100) $aev = $aeh.FindFirst("バージョン情報(A)") $aev.Invoke() [System.Threading.Thread]::Sleep(2000) $aeo = $aec.FindFirst("OK") $aeo.Invoke() [System.Threading.Thread]::Sleep(2000) # TextPatternでは、テキストの挿入が今のところできない、、、 # SendInputの出番か! # Win32APIをコールすべきな気がする。 # 終了 $aecw = $aec.Element.GetCurrentPattern([System.Windows.Automation.WindowPattern]::Pattern) $aecw.Close()