UIAutomation识别UI元素

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中有如下几个重要属性:

  1. AutomationIdProperty: 通过AutomationId来查找AutomationElement。
  2. NameProperty:通过控件的Name属性来查找AutomationElement。
  3. ControlType:通过控件的类型来查找AutomationElement
  4. AutomationId: 唯一地标识自动化元素,将其与同级相区分。
  5. 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

 

根据UIAutomation封装了很多自定义方法 现在只需要实例化之后 直接调用方法即可完成。比如单击某个按钮,现在只需要直接调用ClickElement,非常实用。 ClickElement 单击指定的自动化元素 DisselectAllDataGridRow 不选中所有行 DisselectDataGridRow 不选中特定的某一行 FocusWindow 获取窗口焦点 GetAllElement 获取指定父自动化元素下的所有激活的控件 GetAllElementDetails 获取指定自动化元素下的详细信息包括AutomationID,ControlType以及Name GetAllMenus 获取所有菜单项 GetAllSubMenus 获取某个菜单下的所有子菜单项 GetColumnsFromGridLine 获取指定行的所有列 GetColumnValuesFromGridLine 获取行的每一列数据 GetControlType(AutomationElement) 获取制动自动化元素的控件类型 GetControlType(TypeOfControl) 获取UIAutomation的控件类型 GetDocumentText 获取document控件的值 GetElementByID 获取父自动化元素下指定元素控件ID的引用 GetElementByName 获取父自动化元素下的指定子元素的引用 GetElementsByControlType 获取父自动化元素下的特定类型的所有自动化元素 GetGridLinesFromDataGrid 获取网格控件的全部行元素的引用 GetHeaderFromDataGrid 获取指定网格控件的标题栏引用 GetMenuBar 获取菜单栏控件 GetMenuByName 通过特定的名称去获取菜单UI自动化元素 GetName 获取指定自动化元素的名称 GetSubMenuByName 获取主菜单下的指定子菜单项的引用 GetValue 获取指定自动化元素的值 GetWindowByName(String) 获取desktop下的指定窗口名称的子UI自动化元素 GetWindowByName(String, AutomationElement) 获取特定父UI自动化元素下的制定窗口名称的子UI自动化元素 GetWindowList() 获取当前桌面根下所有的UI自动化元素下 GetWindowList(AutomationElement) 获取特定父UI自动化元素下的所有窗口的名称 RefindMainApplication 重新获取desktop下的指定窗口的自动化元素引用 SelectAllDataGridRow 选中所有行 SelectDataGridRow(AutomationElement) 选中特定的某一行 SelectDataGridRow(AutomationElement, Boolean) 将特定的DateGridRow加入选中项中 SelectValueInComboBox 从下拉框中选中指定值的项 SelectValueInListBox 从列表中选中指定值的项 SetValue 给予指定自动化元素赋值 以上的方法还不是很完善 正在完善中。如果有什么意见和建议,请发送邮件获取 chenxu7601257@qq.com 如果你看了这个帮助文件之后觉得有用的,请发邮件获取,我将把dll文件给你。谢谢。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值