如何(正确)缓存AutomationElements以备将来使用?

时间:2012-03-28 16:06:45

标签: c# .net performance automation microsoft-ui-automation

在我的测试应用程序中,我不断打开并重新打开表单。每次打开表单时,我必须将表单上的所有元素都放到AutomationElementCollection中,以便我可以对元素进行操作。但是,重复获取这些元素似乎很昂贵(由于树导航/上下文切换等)。

我试图在获取元素的方法周围设置一个布尔值。如果第一次调用该方法,它将正常运行,并将布尔值设置为true。如果第二次调用该方法,它将无法执行任何操作,因为已经填充了数组。

但是,当我尝试对阵列中的任何AutomationElement执行操作时(第二次),这些元素似乎不可用。关闭表单会以某种方式“禁用”这些元素吗?每次打开表单时,我是否必须找到这些元素,以便它们“新鲜”?

我查看了CacheRequest方式,但这似乎只适用于访问属性/模式,而不是元素。

以下是代码/错误消息:

AutomationElement GAP;
AutomationElementcollection GAP1;
private bool initGAP1 = false;
    public void initGAP()
    {
        if (!initGAP1)
        {
            int refnum = ...;
            int refnum2 = ...;
            AutomationElementCollection temp = MMChildren[refnum].FindAll(TreeScope.Children, findCondition);
            GAP = temp.FindAll(TreeScope.Children, findCondition)[refnum2];
            GAP1 = GAP.FindAll(TreeScope.Children, findCondition); //this contains the elements I want to operate on
            initGAP1 = true;
        }
    }

System.Windows.Automation.ElementNotEnabledException:抛出了类型'System.Windows.Automation.ElementNotEnabledException'的异常。

1 个答案:

答案 0 :(得分:2)

您需要为每个新窗口重新获取自动化元素。据我了解UI自动化框架,它为您提供了调查运行窗口的方法。它将使用不同的技术收集信息,具体取决于目标应用程序使用的框架类型。在您的情况下,如果您创建和销毁窗口的实例,它们将被视为不同的AutomationElements,因为它们是不同的窗口(基本上它们在操作系统中具有不同的窗口句柄)。即使底层控制代码相同,它们也是针对OS的不同实例,因此也就是UI自动化。

如果您遇到了traversion中的性能问题,那么可能值得考虑使用UI Automation COM API,这在某些操作上要快得多。