【視頻教程】使用UIAutomation開發軟件外掛

         UIAutomation是.Net 3.5以後提供的「界面自動化測試」技術,原本是給測試人員用的,不過UIAutomation因爲也是界面自動操做的技術,比直接使用keybd_event、GetWindowText等Win32的API進行界面模擬操做簡單不少,所以也能夠用UIAutomation作軟件的「外掛」。html

         我手頭正好有這樣一個需求,如鵬網有一個內部使用的一個工具(購買的第三方軟件),用於根據學生的機器碼計算「播放密碼」,這個工具只提供了圖形化的界面:程序員

 

         輸入機器碼以後點擊【建立播放密碼】按鈕就能生成播放密碼。數據庫

         如鵬網第二期學習輔助系統的開發中須要開發「自動生成播放密碼」的功能,也就是學生在瀏覽器中輸入他的機器碼,網站自動計算他的播放密碼。瀏覽器

         因爲這個工具只提供了圖形化的界面,沒有提供API,因此我就想到使用模擬點擊的方法來進行「自動化」,直接使用Win32太麻煩,AutoIt使用還要註冊組件,所以就想到了UIAutomation。緩存

         完成的效果以下:安全

  

         下面分享一下主要技術。網絡

         學習UIAutomation以前必定要知道,Windows中的程序界面元素都是由「窗口組成的」(DirectUI等除外),按鈕、文本框等都是窗口,窗口之間也有父子關係。Windows桌面是全部窗口的根窗口。架構

         UIAutomation支持普通Win32程序(不是VC++、.Net開發的也支持,由於本質上都是Win32程序)和WPF程序,可是不支持普通的DirectUI窗口(好比QQ、瀏覽器)。ide

         使用UIAutomation以前先要添加對UIAutomationClient、 UIAutomationProvider、 UIAutomationTypes三個程序集的引用。全部的界面元素都是由AutomationElement組成,每一個窗口就是一個AutomationElement,所以AutomationElement以前也有父子結構。函數

         可使用AutomationElement.RootElement得到桌面的根元素;使用AutomationElement.FromHandle(IntPtr hwnd)從Win32窗口句柄拿到AutomationElement對象。

         拿到一個AutomationElement一般要遍歷他的子元素。遍歷子元素以前須要先了解「遍歷條件」的概念,遍歷條件就是按照什麼樣的條件去搜索子元素。全部的條件都繼承自Condition類,Condition類的主要子類有PropertyCondition、AndCondition 、NotCondition 、OrCondition,這些之類之間能夠進行復合的組合,造成各類複雜的遍歷條件。

         PropertyCondition是根據屬性的名字和值進行過濾的。它構造函數的第一個參數爲屬性的名字,全部支持的屬性都在AutomationElement的***Property這些靜態成員中;構造函數的第二個參數爲被比較的值。又可使用AndCondition、NotCondition、OrCondition把各個條件進行復雜的邏輯組合。好比下面的conditionBtn9就是「類名爲Button而且名字爲9」的條件:

Condition conditionBtn9 = new AndCondition(
                new PropertyCondition(AutomationElement.ClassNameProperty, "Button"),
                new PropertyCondition(AutomationElement.NameProperty, "9")
                );

  

         Condition類有兩個固定的值,Condition. TrueCondition表明永遠爲True的條件,Condition. FalseCondition表明永遠爲False的條件(應該不多用)

         咱們可使用AutomationElement的FindAll或者FindFirst方法進行元素的遍歷。FindAll是獲取全部符合遍歷條件的AutomationElement,所以是返回AutomationElementCollection集合,而FindFirst是返回第一個符合遍歷條件的AutomationElement,所以是返回AutomationElement。

         FindFirst、FindAll的第一個參數表明搜索的範圍,最經常使用的就是TreeScope.Children和TreeScope.Descendants,TreeScope.Children表明在直接子節點中搜索,而TreeScope.Descendants表明遞歸的在全部子孫節點中搜索。FindFirst、FindAll的第二個參數表明搜索條件。

         定位到要操做的AutomationElement以後,能夠進行模擬點擊(好比按鈕)或者讀寫值(好比輸入框)。好比下面的代碼中element指向的是一個按鈕,下面的代碼就是模擬點擊這個按鈕:

var clickPattern = (InvokePattern)element.GetCurrentPattern(InvokePattern.Pattern);
clickPattern.Invoke();

  

    好比下面的代碼中element指向的是一個文本框,下面的代碼就是使用字符串填充這個輸入框:

ValuePattern valuePattern = (ValuePattern)element.GetCurrentPattern(ValuePattern.Pattern);
valuePattern.SetValue(「如鵬網」);

  

    下面是我實現的一個模擬點擊計算器計算兩個數的乘法的數:

AutomationElement desktop = AutomationElement.RootElement;
var calcFrame1 = desktop.FindFirst(TreeScope.Children,
new PropertyCondition(AutomationElement.ClassNameProperty, "CalcFrame"));

ClickCalcButton(calcFrame1, "3");
ClickCalcButton(calcFrame1, "6");
ClickCalcButton(calcFrame1, "5");
ClickCalcButton(calcFrame1, "*");
ClickCalcButton(calcFrame1, "1");
ClickCalcButton(calcFrame1, "2");
ClickCalcButton(calcFrame1, "=");

  

其中ClickCalcButton是我封裝的一個方法:

private static void InvokeButton(AutomationElement e)
{
    InvokePattern invoke = (InvokePattern)e.GetCurrentPattern(InvokePattern.Pattern);
    invoke.Invoke();
}

private static void ClickCalcButton(AutomationElement calcFrame1, string name)
{
    Condition conditionBtnPlus = new AndCondition(
       new PropertyCondition(AutomationElement.ClassNameProperty, "Button"),
       new PropertyCondition(AutomationElement.NameProperty, name)
       );
    var btn = calcFrame1.FindFirst(TreeScope.Descendants, conditionBtnPlus);
    if (btn == null)
    {
throw new Exception("找不到名字爲"+name+"的計算器按鈕");
    }
    InvokeButton(btn);
}

  

     文章篇幅有限,特別是對於一些沒有Win32基礎的朋友,光看上面的文字會不太容易懂,所以我錄製了一套大約90分的視頻教程,詳細的講解了UIAutomation的使用,但願可以幫到你們。

     視頻教程地址以下 http://www.rupeng.com/Courses/Chapter/298

如鵬網.Net培訓班正在報名,有網絡的地方就能夠參加如鵬網的學習,學完就能高薪就業,點擊此處瞭解

 

    三年前只要懂「三層架構」就能夠說「精通分層架構」;如今則須要懂IOC(AutoFac等)、CodeFirst、lambda、DTO等才值錢;

    三年前只要會SQLServer就能夠說本身「精通數據庫開發」;如今則需還須要掌握MySQL等開源數據庫才能說是「.Net開源」時代的程序員;

    三年前只要會進行用戶上傳內容的安全性處理便可;如今則須要熟悉雲存儲、CDN等才能在雲計算時代遊刃有餘;

    三年前只要掌握Lucene.Net就會說本身「熟悉站內搜索引擎開發」;如今你們都用ElasticSearch了,你還用Lucene.Net就太老土了;

    三年前發郵件仍是用SmtpClient;如今作大型網站發郵件必須用雲郵件引擎;

    三年前緩存就是Context.Cache;如今則是Redis、Memcached的天下;

    如鵬網再次引領.Net社區技術潮流!點擊此處瞭解如鵬網.Net最新課程

相關文章
相關標籤/搜索