UIAutomtion中主要用AutomationElement 类来 表示 UI 自动化目录树中的一个 UI 自动化元素,并包含由 UI 自动化客户端应用程序用作标识符的值。
添加UIAutomation
在reference中添加UIAutomationClient,UIAutomationTypes,UIAutomationProvider 和UIAutomationClientsideProviders。
(Donet 3.0以上的项目中才有)
如何识别一个窗口。
先启动calc.exe.
- using System.Diagnostics;
- using System.Windows.Automation;
- ...
- void GetCalc()
- {
- //通过Process的Handle获得AutomationElement
- Process[] p = Process.GetProcessesByName("calc");
- AutomationElement CalcWindows = AutomationElement.FromHandle(p[0].MainWindowHandle);
- }
还有一种方法
- using System.Windows.Automation;
- ...
- void GetCalc()
- {
- //先识别桌面,再在桌面中查找Window类型且名字叫"Calculator"(英文系统)
- AutomationElement RootElement=AutomationElement.RootElement;
- AutomationElement CalcWindows=RootElement.FindFirst(TreeScope.Children,
- new AndCondition(
- new PropertyCondition(AutomationElement.ControlTypeProperty,ControlType.Window),
- new PropertyCondition(AutomationElement.NameProperty,"Calculator")
- ));
- }
识别UI元素
找到窗口就可以开始找窗口上的UI元素了。
比如我想找Calculator上的文本框
可以用如下代码实现:
- using System.Windows.Automation;
- ...
- //找到Desktop
- AutomationElement Desktop = AutomationElement.RootElement;
- //找到Calculator窗口
- AutomationElement CalcWindows = Desktop.FindFirst(TreeScope.Children,
- new AndCondition(
- new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window),
- new PropertyCondition(AutomationElement.ClassNameProperty, "SciCalc")
- )
- );
- //找到Calculator的Edit控件
- AutomationElement CalcEdit=CalcWindows.FindFirst(TreeScope.Children,
- new AndCondition(
- new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit),
- new PropertyCondition(AutomationElement.ClassNameProperty, "Edit")
- )
- );
AutomationElement.FindFirst 的方法
public AutomationElement FindFirst( TreeScope scope, Condition condition)
TreeScope是个枚举类型
成员名称 | 说明 |
Element | 指定搜索包括元素本身。 |
Children | 指定搜索包括元素的直接子级。 |
Descendants | 指定搜索包括元素的子代(包括子级)。 |
Parent | 指定搜索包括元素的父级。不支持。 |
Ancestors | 指定搜索包括元素的上级(包括��级)。不支持。 |
Subtree | 指定搜索包括搜索的根和全部子代。 |
Children和Descendants比较常用。Subtree也用比较多。
Condition 类
在 UI 自动化目录树中搜索元素时应用于筛选的条件的基类型。<div><p> </p><p>主要都使用下面几个子类</p><p> <a target=_blank href="http://msdn.microsoft.com/zh-cn/library/system.windows.automation.andcondition(v=VS.90).aspx" style="color:rgb(51, 102, 153);"><span style="color:rgb(19, 100, 196);">System.Windows.Automation.AndCondition</span></a> <a target=_blank href="http://msdn.microsoft.com/zh-cn/library/system.windows.automation.notcondition(v=VS.90).aspx" style="color:rgb(51, 102, 153);"><span style="color:rgb(19, 100, 196);">System.Windows.Automation.NotCondition</span></a> <a target=_blank href="http://msdn.microsoft.com/zh-cn/library/system.windows.automation.orcondition(v=VS.90).aspx" style="color:rgb(51, 102, 153);"><span style="color:rgb(19, 100, 196);">System.Windows.Automation.OrCondition</span></a> <a target=_blank href="http://msdn.microsoft.com/zh-cn/library/system.windows.automation.propertycondition(v=VS.90).aspx" style="color:rgb(51, 102, 153);"><span style="color:rgb(19, 100, 196);">System.Windows.Automation.PropertyCondition</span></a></p><p> </p><p><a target=_blank href="http://msdn.microsoft.com/zh-cn/library/system.windows.automation.andcondition(v=VS.90).aspx" style="color:rgb(51, 102, 153);"><span style="color:rgb(19, 100, 196);">AndCondition</span></a> 表示一个与(And)条件 <a target=_blank href="http://msdn.microsoft.com/zh-cn/library/system.windows.automation.notcondition(v=VS.90).aspx" style="color:rgb(51, 102, 153);"><span style="color:rgb(19, 100, 196);">NotCondition</span></a> 表示一个非(Not)条件</p><p><a target=_blank href="http://msdn.microsoft.com/zh-cn/library/system.windows.automation.orcondition(v=VS.90).aspx" style="color:rgb(51, 102, 153);"><span style="color:rgb(19, 100, 196);">OrCondition</span></a> 表示一个或(Or)条件</p><p> </p><p><span style="color:rgb(19, 100, 196);">PropertyCondition </span><span style="color:rgb(0, 0, 0);">它测试属性是否具有指定的值</span></p><p> </p><p>可以在UISpy的右边Identification中找到相应的值。</p><p>一般用ControlType,ClassName, Automationid 和 Name 就够用了。其他的一般较少使用。</p><p> </p><p> <img src="http://hi.csdn.net/attachment/201012/23/0_1293071533srK2.gif" alt="" width="671" height="575" /></p><p> </p><p> </p><p> </p></div>
有时候我们会要捕捉一组有相同属性的控件就要用到AutomationElementCollection 类。
AutomationElementCollection 类
表示 <a target=_blank href="http://msdn.microsoft.com/zh-cn/library/system.windows.automation.automationelement(v=VS.90).aspx" style="color: rgb(51, 102, 153); text-decoration: none;"><span style="color: rgb(150, 11, 180);">AutomationElement</span></a> 对象的集合
比如我们要捕捉Calculator上的所有Button.
<img src="http://hi.csdn.net/attachment/201012/23/0_1293079000DW98.gif" alt="" style="border: none; max-width: 100%;" />
<div class="dp-highlighter bg_c-sharp" style="font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; width: 700.90625px; overflow: auto; padding-top: 1px; margin: 18px 0px !important; background-color: rgb(231, 229, 220);"><div class="bar" style="padding-left: 45px;"><div class="tools" style="padding: 3px 8px 10px 10px; font-stretch: normal; font-size: 9px; line-height: normal; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; color: silver; border-left-width: 3px; border-left-style: solid; border-left-color: rgb(108, 226, 108); background-color: rgb(248, 248, 248);"><strong>[c-sharp]</strong> <a target=_blank href="http://blog.csdn.net/vbic0673/article/details/6093844#" class="ViewSource" title="view plain" style="color: rgb(160, 160, 160); text-decoration: none; border: none; padding: 1px; margin: 0px 10px 0px 0px; font-size: 9px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_plain.gif); background-attachment: initial; background-color: inherit; background-size: initial; background-origin: initial; background-clip: initial; background-position: 0% 0%; background-repeat: no-repeat;">view plain</a><a target=_blank href="http://blog.csdn.net/vbic0673/article/details/6093844#" class="CopyToClipboard" title="copy" style="color: rgb(160, 160, 160); text-decoration: none; border: none; padding: 1px; margin: 0px 10px 0px 0px; font-size: 9px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_copy.gif); background-attachment: initial; background-color: inherit; background-size: initial; background-origin: initial; background-clip: initial; background-position: 0% 0%; background-repeat: no-repeat;">copy</a><div style="position: absolute; left: 538px; top: 923px; width: 18px; height: 18px; z-index: 99;"></div></div></div><ol start="1" class="dp-c" style="padding: 0px; border: none; color: rgb(92, 92, 92); margin: 0px 0px 1px 45px !important; background-color: rgb(255, 255, 255);"><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"><span class="keyword" style="margin: 0px; padding: 0px; border: none; color: rgb(0, 102, 153); font-weight: bold; background-color: inherit;">using</span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> System.Windows.Automation; </span></span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; background-color: rgb(248, 248, 248);"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> </span></li><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;">.... </span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; background-color: rgb(248, 248, 248);"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> </span></li><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"><span class="comment" style="margin: 0px; padding: 0px; border: none; color: rgb(0, 130, 0); background-color: inherit;">//找到Desktop </span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> </span></span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; background-color: rgb(248, 248, 248);"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;">AutomationElement Desktop = AutomationElement.RootElement; </span></li><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"><span class="comment" style="margin: 0px; padding: 0px; border: none; color: rgb(0, 130, 0); background-color: inherit;">//找到Calculator窗口 </span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> </span></span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; background-color: rgb(248, 248, 248);"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;">AutomationElement CalcWindows = Desktop.FindFirst(TreeScope.Children, </span></li><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> <span class="keyword" style="margin: 0px; padding: 0px; border: none; color: rgb(0, 102, 153); font-weight: bold; background-color: inherit;">new</span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> AndCondition( </span></span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; background-color: rgb(248, 248, 248);"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> <span class="keyword" style="margin: 0px; padding: 0px; border: none; color: rgb(0, 102, 153); font-weight: bold; background-color: inherit;">new</span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window), </span></span></li><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> <span class="keyword" style="margin: 0px; padding: 0px; border: none; color: rgb(0, 102, 153); font-weight: bold; background-color: inherit;">new</span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> PropertyCondition(AutomationElement.ClassNameProperty, </span><span class="string" style="margin: 0px; padding: 0px; border: none; color: blue; background-color: inherit;">"SciCalc"</span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;">) </span></span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; background-color: rgb(248, 248, 248);"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> ) </span></li><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> ); </span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; background-color: rgb(248, 248, 248);"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"><span class="comment" style="margin: 0px; padding: 0px; border: none; color: rgb(0, 130, 0); background-color: inherit;">//找到全部在Calculator子自动化树下的Button控件</span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> </span></span></li><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;">AutomationElementCollection Buttons = CalcWindows.FindAll(TreeScope.Children, </span></li><li style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important; background-color: rgb(248, 248, 248);"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> <span class="keyword" style="margin: 0px; padding: 0px; border: none; color: rgb(0, 102, 153); font-weight: bold; background-color: inherit;">new</span><span style="margin: 0px; padding: 0px; border: none; background-color: inherit;"> PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button) </span></span></li><li class="alt" style="border-style: none none none solid; border-left-width: 3px; border-left-color: rgb(108, 226, 108); list-style: decimal-leading-zero outside; color: inherit; line-height: 18px; margin: 0px !important; padding: 0px 3px 0px 10px !important;"><span style="margin: 0px; padding: 0px; border: none; color: black; background-color: inherit;"> ); </span></li></ol></div>
AutomationElementCollection主要是通过AutomationElement.FindAll方法获得,
AutomationElement.FindAll的语法和AutomationElement.FindFirst一样.
<pre style="white-space: pre-wrap; word-wrap: break-word;"><span style="color: blue;">public</span> AutomationElementCollection FindAll( TreeScope scope, Condition condition )
在一般情况下用FindFirst和FindAll只可以找到在UISpy中的Control View中有显示的AutomationElement。
但是有时候有的AutomationElement在Control View没有显示,但是在Raw View中确存在。特别容易出现在自定义控件中。
在一个Treeview中就每有一个Text AutomationElement只在RAW View中有显示。
这时候我们可以用TreeWalker 类查找在Raw View中的AutomationElement。
- string get_itemname(AutomationElement n)
- {
- //在AutomationElement中找子Element
- for (AutomationElement elementNode = TreeWalker.RawViewWalker.GetFirstChild(n); elementNode != null; elementNode = TreeWalker.RawViewWalker.GetNextSibling(elementNode))
- {
- //判断AutomationElement的类型
- if (elementNode.Current.ControlType.ProgrammaticName == "ControlType.Text")
- {
- return elementNode.Current.Name;
- }
- }
- return "";
- }