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 ,在此主要做自己的收藏,也借花献佛给需要的人。