65.9K
CodeProject 正在变化。 阅读更多。
Home

WPF UI 自动化

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (45投票s)

2009年2月4日

CPOL

5分钟阅读

viewsIcon

250833

downloadIcon

7047

本文演示了如何创建一个简单的 Windows UI 自动化应用程序。

引言

概述

Microsoft UI 自动化是 Microsoft Windows 的新辅助功能框架,适用于支持 Windows Presentation Foundation (WPF) 的所有操作系统。UI 自动化提供对桌面大多数用户界面 (UI) 元素的程序化访问。

本文演示了如何使用 UI 自动化来控制一个简单的应用程序。基本原理是,控制器应用程序将搜索正在运行的测试应用程序,如果找到该应用程序,我们将搜索 UI 元素层级,然后发送模拟数据。

适用于

  • Microsoft® .NET Framework 3.0
  • Microsoft® Windows Presentation Foundation - WPF
  • Microsoft® UI Automation Framework
控制器应用程序

UI_Automation_Controller.png

测试应用程序

UI_Automation_Test.png

UI 自动化框架

该框架的核心思想是它提供了对 Win 应用程序中可见的用户界面元素层级的访问。可以想象层级的根元素是桌面,所有正在运行的应用程序都是根的第一级节点(子节点),依此类推,每个可见窗体都可以细化到其控件,控件再到其子控件,等等。此树中的每个节点都称为 UI 元素。

该框架通过提供对这些 UI 元素及其属性的访问来帮助我们。该框架支持的主要功能有:

  • 搜索支持,允许您查找所需的用户界面组件。
  • 过滤元素的树形结构;例如,在查询元素层级时,我们可以仅获取启用的控件。
  • 允许您与 UI 元素进行交互;例如,您可以从您的应用程序中以编程方式点击(一个包含在不同应用程序中的)按钮。
  • 订阅事件;这有助于我们监视 UI 元素并处理外部事件。

UI 自动化 API

System.Windows.Automation 是 UI 自动化框架的主要命名空间,它提供了与 UI 元素(也称为 AutomationElement)交互的支持。AutomationElement 是框架中的主要类,对应一个用户界面组件(窗口、列表、按钮等)。此命名空间的主要功能与搜索 AutomationElement 对象、与不同控件模式交互或订阅 UI 自动化事件相关。

AutomationElement 包含一个名为 RootElement 的属性,它包含对桌面对应 UI 元素的引用,该引用实际上返回一个 AutomationElement

关于搜索支持,AutomationElement 类包含 FindFirst()FindAll() 方法。

public AutomationElement FindFirst(TreeScope scope, Condition condition)

我们可以使用 FindFirst 方法来搜索与传入的条件匹配的特定 AutomationElement 。为了调用此方法,我们需要传递搜索范围(TreeScope 枚举的实例),例如搜索子项的第一级,或搜索所有后代。除了 scope 参数,我们还必须传递用于识别所需 AutomationElement 的条件。我们将以扩展 Condition abstract 类的类的实例作为条件。这样,我们可以使用 PropertyCondition (用于测试属性是否具有特定值),但也有:AndConditionNotConditionOrCondition 类。

public AutomationElementCollection FindAll(TreeScope scope, Condition condition);

FindFirst 类似,FindAll() 允许我们使用上述参数查询 UI 自动化树,但返回一个 AutomationElement 集合,该集合通过了搜索条件。

基于上述细节,我们可以编写一行简单的代码,该代码将搜索根元素的所有后代,查找名称等于“Notepad”的 UI 元素。

AutomationElement appElement = AutomationElement.RootElement.FindFirst
(TreeScope.Descendants,new PropertyCondition(AutomationElement.NameProperty, "Notepad"))

实现

为了使用 UI 自动化 API,我们需要添加对以下程序集的引用:

  • UIAutomationClient.dll
  • UIAutomationTypes.dll

对于这个简单的实现,我使用了基类 AutomationElement,正如我之前所说,它保留了桌面应用程序中 UI 元素的引用。关键在于,我们需要从桌面元素(即根元素 AutomationElement.RootElement)开始,然后在 RootElement 的所有子对象中搜索标题为“UI Automation Test Window”的测试应用程序。在获得测试应用程序的 AutomationElement 的有效引用后,我们就可以与其中包含的各种控件进行交互了。这样,控制器应用程序将为两个 TextBox 控件设置一些值。

AutomationElementHierarchi.png

AutomationElement rootElement = AutomationElement.RootElement;
if (rootElement != null)
{
    Automation.Condition condition = new PropertyCondition
        (AutomationElement.NameProperty, "UI Automation Test Window");

    AutomationElement appElement = rootElement.FindFirst(TreeScope.Children, condition);

    if (appElement != null)
    {
        AutomationElement txtElementA = GetTextElement(appElement, "txtA");
        if (txtElementA != null)
        {
            ValuePattern valuePatternA = 
              txtElementA.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
            valuePatternA.SetValue("10");
        }

        AutomationElement txtElementB = GetTextElement(appElement, "txtB");
        if (txtElementA != null)
        {
            ValuePattern valuePatternB = 
              txtElementB.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
            valuePatternB.SetValue("5");
        }
    }

以下是 GetTextElement 函数:

private AutomationElement GetTextElement(AutomationElement parentElement, string value)
{
    Automation.Condition condition = 
      new PropertyCondition(AutomationElement.AutomationIdProperty, value);
    AutomationElement txtElement = parentElement.FindFirst
                (TreeScope.Descendants, condition);
    return txtElement;
}

如上面的代码所示,我们正在使用一个控件模式 ValuePattern。UIA (UI Automation) 使用控件模式来表示常用控件。控件模式通过提供方法、事件和属性来定义控件中可用的特定功能。控件模式中声明的方法允许 UIA 客户端操作控件,例如 ValuePattern.SetValue() 方法。除了表示存储 string 值的控件的 ValuePattern,作为另一个控件模式的示例,我们可以考虑 Invoke 模式控件 InvokePattern,它表示可调用的控件,例如按钮。为了使用控件模式,我们需要查询对象以查看支持哪些接口,并且只有在获得有效的控件模式后,我们才能通过使用其方法、事件和属性与其进行交互。以下列表显示了最常见的控件模式:

  • SelectionPattern - 用于支持选择的控件,例如 ListBoxComboBox
  • TextPattern - 用于编辑控件
  • ValuePattern - 用于在不支持多个值的控件上获取/设置
  • InvokePattern - 用于可调用控件
  • ScrollPattern - 用于带有滚动条的控件
  • RangeValuePattern - 用于具有值范围的控件

下面的示例显示了如何使用 InvokePattern;换句话说,它将点击 parentElement 中包含的按钮。

{
    Automation.Condition condition = new PropertyCondition
            (AutomationElement.AutomationIdProperty, "Button1");
    AutomationElement btnElement = parentElement.FindFirst
            (TreeScope.Descendants, condition);
    
    InvokePattern btnPattern = 
    btnElement.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
    btnPattern.Invoke();
}

结论

UI 自动化是一个强大的辅助功能框架,它允许您控制其他应用程序。它可以用于开发自动化 UI 测试/调试应用程序等。

关于这个主题,还有更多内容即将推出。

历史

  • 2009 年 2 月 4 日:初始发布
  • 2009 年 2 月 5 日:文章更新
  • 2009 年 2 月 19 日:文章文本更新
© . All rights reserved.