MS UI Automation(Microsoft User Interface Automation:UIA)是随.net framework3.0一起发布的,虽然在如今这个几乎每天都有各种新名词、新技术出来的所谓的21世纪,它显得已经有些过时了。前些日子,正好一个项目,可以用到它,又重新整理了一下:
什么是MS UI Automation
MS UI Automation是MSAA技术的一个替代品:即让控件和应用程序具有更好的可达性(accessible),关于软件的可达性,具体大家可参考一本<<Engineering Software for Accessibility>>的书,该书结合MS UIA,讲述了如何在软件开发的整个生命周期中,让软件具备可达性。回到MS UIA,简单来讲,它就是几个dll,提供了一套API和Interface,及其相应的模式,让软件的开发者遵循该模式去实现相应的interface,从而软件的使用者(不仅仅是客户,还包括例如测试人员想编写一些自动化测试代码来完成程序相关的业务逻辑)能更好的使用该软件。
UI Automation是Microsoft .NET 3.0框架下提供的一种用于自动化测试的技术,是在MSAA基础上建立的,MSAA就是Microsoft Active Accessibility。UI Automation在某些方面超过了MSAA,UI自动化提供了Windows Vista中,微软Windows XP的全部功能,和Windows Server 2003。
在UI Automation中,所有的窗体、控件都表现为一个AutomationElement, AutomationElement 中包含此控件或窗体的属性,在实现自动化的过程中,我们通过其相关属性进行对控件自动化操作。对于UI用户界面来说,所有显示在桌面上的UI,其实际是一个UI Tree,根节点是desktop。我们可以使用UI Spy或者是SPY++来获得Window和Control的相关信息。在UI Automation里,根节点表示为AutomationElemnet.RootElement. 通过根节点,我们可以通过窗体或控件的Process Id、Process Name或者Window Name找到相应的子AutomationElement,例如Dialog、Button、 TextBox、Checkbox等标准控件,通过控件所对应的Pattern进行相关的操作。
UI Automation structure
如下图所示:
1. 在服务端由UIAutomationProvider.dll和UIAutomationTypes.dll提供。
2. 在客户端由UIAutomationClient.dll和UIAutomationTypes.dll提供。
3. UIAutomationCore.dll为UI自动化的核心部分,负责Server端和Client端的交互。
4. UIAUtomationClientSideProvides.dll为客户端程序提供自动化支持。
Summary
本文主要简单介绍了UI Automation相关结构以及核心库。
Open Source code
Github: https://github.com/cumtkangyi/ATP
当前项目进行三个多月了,好久也没有写日志了;空下点时间,补写下N久没写的日志
介绍下两个工具
我本人正常使用的UISpy.exe工具和inspect.exe工具
这是UISPY工具使用的图,正常使用到的几个属性
这里重点说一下微软件的UI Automation中的重要类型是AutomationElement
图上的文本元素可通过AutomationElement,上级类型来获取子节点中的窗体或控件 ,也可以根据类型获取
如图所示:我们通过UIspy工具找到相应的控件名称,就可以用以下语法和属性获取到窗体或控件
AutomationElement ControlTypeComboBox = grdClassBook.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ComboBox)); AutomationElement cellElement = ControlTypeComboBox.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "ListBox"));
在UI Automation中有如下几个重要属性:
- AutomationIdProperty: 通过AutomationId来查找AutomationElement。
- NameProperty:通过控件的Name属性来查找AutomationElement。
- ControlType:通过控件的类型来查找AutomationElement
- AutomationId: 唯一地标识自动化元素,将其与同级相区分。
- Name: WPF 按钮的Content 属性、Win32 按钮的Caption 属性以及 HTML 图像的ALT 属性都映射到 UI 自动化视图中的同一个属性Name
说明 :
AutomationElement 是微软指定的类型
PropertyCondition类是用来对相关属性进行条件匹配,在控件树中查找控件时,可以通过最佳匹配来找到相应的控件。
有时UISPY工具有的地方获取不到窗体或控件元素
所以我有时会用inspect.exe工具;自己设置下属性,跟随鼠标,也能把控件元素指定出来
如图:
也能找到相应的元素属性,我比较推荐这个工具,因为这个工具是深度获取元素,本人在win7下面感觉这个工具比UISPY工具要快得多。
比较简单的抓图解释。。。自己日志记录,如有不同意见的欢迎拍砖。
public void InvokeAutomationElement(AutomationElement automationElement) { var invokePattern = automationElement.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern; invokePattern.Invoke(); }
鼠标事件
#define WM_MOUSEFIRST 0x0200
#define WM_MOUSEMOVE 0x0200
#define WM_LBUTTONDOWN 0x0201
#define WM_LBUTTONUP 0x0202
#define WM_LBUTTONDBLCLK 0x0203
#define WM_RBUTTONDOWN 0x0204
#define WM_RBUTTONUP 0x0205
#define WM_RBUTTONDBLCLK 0x0206
#define WM_MBUTTONDOWN 0x0207
#define WM_MBUTTONUP 0x0208
#define WM_MBUTTONDBLCLK 0x0209
Winuser.h文件里面
截取整个桌面
[c-sharp] view plain copy
public static Image Cut()
{
Rectangle rc = Screen.PrimaryScreen.Bounds;
int iWidth = rc.Width;
int iHeight = rc.Height;
Image myImage = new Bitmap(iWidth, iHeight);
Graphics.FromImage(myImage).CopyFromScreen(new System.Drawing.Point(0, 0), new System.Drawing.Point(0, 0), new System.Drawing.Size(iWidth, iHeight));
return myImage;
}
截取一个Rectangle.
[c-sharp] view plain copy
public static Image Cut(Rectangle rect)
{
Rectangle rc = rect;
int iWidth = rc.Width;
int iHeight = rc.Height;
Image myImage = new Bitmap(iWidth, iHeight);
Graphics.FromImage(myImage).CopyFromScreen(rc.Location, new System.Drawing.Point(0, 0), new System.Drawing.Size(iWidth, iHeight));
return myImage;
}
截取 x,y 点 weight,height
[c-sharp] view plain copy
public static Image Cut(int X, int Y, int Width, int Height)
{
Rectangle rc = new Rectangle(X, Y, Width, Height);
int iWidth = rc.Width;
int iHeight = rc.Height;
Image myImage = new Bitmap(iWidth, iHeight);
Graphics.FromImage(myImage).CopyFromScreen(rc.Location, new System.Drawing.Point(0, 0), new System.Drawing.Size(iWidth, iHeight));
return myImage;
}
http://www.cnblogs.com/kangyi/archive/2009/09/08/1549411.html
http://blog.csdn.net/ffeiffei/article/details/6637418
http://blog.csdn.net/vbic0673/article/details/6089375
https://msdn.microsoft.com/zh-cn/library/ms606775(v=vs.100).aspx
http://www.cnblogs.com/Luouy/p/4204319.html
http://stackoverflow.com/questions/4908906/c-sharp-raise-an-event-when-a-new-process-starts
http://stackoverflow.com/questions/31813622/invoke-on-click-on-a-button-using-ui-automation-with-no-invokepattern-or-clickab
http://stackoverflow.com/questions/10105396/given-an-automation-element-how-do-i-simulate-a-single-left-click-on-it
https://msdn.microsoft.com/en-us/library/ms747211%28v=vs.110%29.aspx