【转】UI Aumation简介

UI Automation是微软.net Framework 3.0所出的. 关于他完整的介绍当然是看msdn了http://msdn.microsoft.com/en-us/library/ms747327.aspx。不过在此罗列我认为有用的信息。

1. 如何使用

    第一步:在VS项目->添加引用->选择UIAutomationClient, UIAutomationTypes, UIAutomationProvider。

    第二步:在项目cs文件中引用其namespace ( using System.Windows.Automation;)

    第三步:就开始在代码中用吧,包括AutomationElement, PropertyCondition 等

2. 其拥有的类的简介

    2.1 简介

          2.1.1 UIAutomation认为每一个控件都是一个AutomationElement. 只是不同的控件有这不同的属性值如name, text等

          2.1.2 桌面被认为是根节点,固定的用AutomationElement.RootElement可以得到桌面

          2.1.3 从桌面开始到其下每个程序,程序下的控件,控件包括的子控件。这些AutomationElement一级一级的扩展,他们有兄弟姐妹,父母子女。形成一个由桌面为尖顶的树。

          2.1.4 既然AutomationElement之间有着一定的关系,自然而然的我们可以通过一定的条件把想要的Element找出来。一般是通过一个或多个PropertyCondition查找到想要的Element

          2.1.5 如果这个AutomationElement及其子孙对象在程序中多处都会需要时,你可以利用cacheRequest将他们放到cache中,来提高他们的访问速度。

    2.2 AutomationElement,可以认为他是UIAutomation的精元。假设已经new了一个对象AutomationElement ae =null;

         2.2.1 非常有用的属性是Current,你可以查看他的name,IsEnabled等信息. 如ae.Current.Name,ae.Current.AutomationId.

这里需要解释一下name一般是c#控件的text属性值automationId一般是c#控件的name属性值。如果使用了非标准控件的话需要注意有时候UIAutomation查不出automationId是什么所以为空或者为动态的数字,这时候需要处理依靠别的属性来定位 

          2.2.2 经常用到的方法有三个:FindAll,FindFirst,TryGetCurrentPattern.。

FindAll和FindFirst都需要两个参数,一个是查找范围TreeScope,一个是查找条件Condition。两者不同顾名思义第一个是返回所有满足条件的collection,第二个是返回符合条件的第一个AutomationElement.

         2.2.3 使用实例,以下方法可以遍历桌面的程序界面对象。

string name = string.Empty;

foreach (AutomationElement ae in AutomationElement.RootElement.FindAll(TreeScope.Children, Condition.TrueCondition))

{

       name += ae.Current.Name+"/r/n";

 }

     2.3 枚举类型TreeScope。常用的是Children(所有子), Descendants(所有子孙)

     2.4 条件Condition,

           2.4.1 简单的有直接true (Condition.TrueCondition)和false (Condition.FalseCondition).

           2.4.2 复杂点的为PropertyCondition,就是设置属性值条件,

如PropertyCondition pc= new PropertyCondition(AutomationElement.NameProperty, value);

           2.4.3 各种条件的交集就是符合所有条件都可以, 如 AndCondition pcTarget = null;

  pcTarget = new AndCondition(

new PropertyCondition(AutomationElement.AutomationIdProperty, nodeAutomationId.InnerText),

new PropertyCondition(AutomationElement.NameProperty, nodeName.InnerText),

new PropertyCondition(AutomationElement.HelpTextProperty, nodeHelpText.InnerText),

new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.LookupById(int.Parse(nodeControlType.InnerText))));

           2.4.4 各种条件的并集就是符合任一条件就可以,如OrCondition pcTarget = null;

pcTarget = new OrCondition (

new PropertyCondition(AutomationElement.AutomationIdProperty, nodeAutomationId.InnerText),

new PropertyCondition(AutomationElement.NameProperty, nodeName.InnerText),

new PropertyCondition(AutomationElement.HelpTextProperty, nodeHelpText.InnerText),

new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.LookupById(int.Parse(nodeControlType.InnerText))));

      2.5 Pattern,可以理解是对于控件的操作。比如button会有InvokePattern,对应的就是click。CheckBox会有TogglePattern,对应的是check操作。需要注意的是在xp上在模态窗口上invoke操作会被阻塞,所以这时候的操作需要选择用api模拟鼠标点击。win7上没有这个问题。实例

 InvokePattern ipItem = null;

 object temp;

 if (ae.TryGetCurrentPattern(InvokePattern.Pattern, out temp))

 {

         ipItem = temp as InvokePattern;

         try

             {

                ipItem.Invoke();

              }

         catch (Exception ex)

              {

                Console.WriteLine("Inovke引发exception:" + ex.Message);

                return ClickByMouse(ae);

              }

}

Pattern一般对应是操作,但是对于控件中用户的输入值有些控件并不是显示在name属性上,而是有专门的TextPattern或者ValuePattern。这个需要自己在UISpy上看看到底是什么pattern。

类的理解不复杂,直接上实例:

object objTemp;

 if (ae.TryGetCurrentPattern(ValuePattern.Pattern, out objTemp))

{

         ValuePattern vp = (ValuePattern)objTemp;

         return vp.Current.Value;

}

      2.6 CacheRequest,将某个对象及其子或子孙放到cache中提高速度。如果有个对象需要经常使用查找子孙对象时可是使用。

使用注意事项:放到cache可以提速但是cache容量有限所以存放时存放太多的对象,如果子孙有上百个时,不建议使用。实例:

CacheRequest cr = new CacheRequest();

cr.TreeFilter = Automation.RawViewCondition;

cr.TreeScope = TreeScope.Subtree;

AutomationElement aeGrandPa;

aeGrandPa = this._element.GetFirstElement(dwGrandPaId);

using (cr.Activate())

{

      aeParent = this._element.GetFirstElement(aeGrandPa, range, type, conditionValue);

}

GetFirstElement为自己写的一个封装了FindFirst的方法

3. 辅助工具介绍

    微软发布了一个类似Spy++的工具叫做UISpy。工具使用就不介绍了。

该文章来源于http://blog.csdn.net/xiao_rory/article/details/5863327 ,在此主要做自己的收藏,也借花献佛给需要的人。

原文地址:https://www.cnblogs.com/keepSmile/p/3135123.html