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