UIAutomation是.Net 3.5之后提供的“界面自动化测试”技术,本来是给测试人员用的,不过UIAutomation由于也是界面自动操作的技术,比直接使用keybd_event、GetWindowText等Win32的API进行界面模拟操作简单很多,因此也可以用UIAutomation做软件的“外挂”。

我手头正好有这样一个需求,如鹏网有一个内部使用的一个工具(购买的第三方软件),用于根据学生的机器码计算“播放密码”,这个工具只提供了图形化的界面:

输入机器码之后点击【创建播放密码】按钮就能生成播放密码。

如鹏网第二期学习辅助系统的开发中需要开发“自动生成播放密码”的功能,也就是学生在浏览器中输入他的机器码,网站自动计算他的播放密码。

由于这个工具只提供了图形化的界面,没有提供API,所以我就想到使用模拟点击的方法来进行“自动化”,直接使用Win32太麻烦,AutoIt使用还要注册组件,因此就想到了UIAutomation。

完成的效果如下:

下面分享一下主要技术。

学习UIAutomation之前一定要知道,Windows中的程序界面元素都是由“窗口组成的”(DirectUI等除外),按钮、文本框等都是窗口,窗口之间也有父子关系。Windows桌面是所有窗口的根窗口。

UIAutomation支持普通Win32程序(不是VC++、.Net开发的也支持,因为本质上都是Win32程序)和WPF程序,但是不支持普通的DirectUI窗口(比如QQ、浏览器)。

使用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

【视频教程】使用UIAutomation开发软件外挂的更多相关文章

  1. Psp个人软件开发软件需求分析和用例分析

    Psp个人软件开发软件需求分析和用例分析 一.需求分析 1.业务需求 1.1 应用背景 开发项目进度计划总是那么不明确,延期经常出现,甚至无法给出一个相对比较明确的延迟时间.这样给市场的推广会带来很大 ...

  2. android开发软件

    android开发软件: http://developer.android.com/sdk/index.html#download

  3. ARM开发软件ADS教程

    ARM开发软件ADS教程 ADS(ARM Developer Suite)是ARM公司推出ARM集成开发环境,操作简单方便,获得广大开发人员的青睐.下面使用ADS v1.2做一个实例教程,帮助大家学会 ...

  4. 在“非软件企业”开发软件的困局 ZT

    软件产品广泛服务于各行业,其开发具有高科技.高投入.高产出.高风险的特点.在项目开发和软件应用中,只有将人员能力的发挥与科学技术的使用应用市场的认识进行最佳的融合,才能发挥软件的效益.普通企业虽涉足软 ...

  5. 10款 Mac 经典原型设计开发软件推荐

    在Mac上有大量强大的开发和设计工具,今天和大家推荐10款Mac上的经典原型设计开发工具,原型设计工具是开发者必备的一款工具,无论是网站开发还是移动APP开发,都需要在前期进行严格细致的原型设计,才能 ...

  6. Java开发软件安装及配置

    2017-6-1 1.jdk 1.8.0_131 安装JDK 选择安装目录 安装过程中会出现两次 安装提示 . 第一次是安装 jdk ,第二次是安装 jre .建议两个都安装在同一个java文件夹中的 ...

  7. 【三分钟视频教程】iOS开发中 Xcode 报 apple-o linker 错误的#解决方案#

      [三分钟视频教程]iOS开发中 Xcode 报 apple-o linker 错误的#解决方案#   同样的道理,指向同一库文件的代码语句如果重复书写,即使重复书写所在的文件名字不同,同样会造成这 ...

  8. Linux下与Windows下开发软件

    Linux下开发程序可以完全发挥自己的聪明才智,因为系统内核是完全开放的.Windows下开发程序就稍微郁闷一点,不论何种语言都必须在调用系统API的基础上开发,因为系统内核是不开放的. 这两种系统正 ...

  9. 苹果Swift可为Windows/Android开发软件了

    http://www.swifthumb.com/article-189-1.html http://iphone.tgbus.com/news/class/201502/20150211103418 ...

随机推荐

  1. .net多线程

    线程 线程池 异步 异步更新winform界面 线程同步

  2. net 调用https接口

    public static void ProcessRequest() { //类似浏览器确认证书合法方法的绑定 ServicePointManager.ServerCertificateValida ...

  3. IE插件BHO

    一丶接口IObjectWithSite //BHO项目(类库)添加引用两个COM //Microsoft HTML Object Library, Microsoft Internet Control ...

  4. 拦截js方法备忘录

    很明显,以下代码拦截了fusion2.dialog.invite,然后在页面执行fusion2.dialog.invite方法的时候修改了参数中的img. <script> var old ...

  5. .net 发展史

    2002年年初 -Visual Studio 2002 & .Net Framework 1.0 2003年春天 -Visual Studio 2003 & .Net Framewor ...

  6. View优化

    前面写了个View画圆弧,为了让他和底层图片效果融合,采用先把圆弧画到和图片一样大小的画布上,然后用canvas的变换位图方法映射过去. bitmapWithReflection = Bitmap.c ...

  7. Stack Overflow is a question and answer site

    http://stackoverflow.com/ _ Stack Overflow is a question and answer site for professional and enthus ...

  8. Html5应用程序缓存ApplicationCache

    应用缓存机制可以参考http://www.w3school.com.cn/html5/html_5_app_cache.asp,不再赘述.利用此机制,html5游戏可以实现和native app类似的 ...

  9. 19. UIAlertController 提示框获取文本内容,打印控制台上

    1.首先定义一个全局字符串变量,方便接收获取的文本内容 2. -(void)viewDidAppear:(BOOL)animated{ UIAlertController * alert = [UIA ...

  10. ROS BY EXAMPLE 1 -- 环境设置与安装

    rbx1 package 的环境设置: sudo apt-get install ros-indigo-turtlebot-bringup \ ros-indigo-turtlebot-create- ...