无法使用UIAutomation

时间:2016-10-24 14:21:48

标签: c# ui-automation

我正在使用Microsoft的UIAutomation库来获取C#。我有一个具有以下属性的元素:

  • LocalizedControlType:“edit”
  • AutomationId:“数据库”
  • Readonly:False
  • 文字字段

我可以使用Inspect读取这些属性。但是,我无法在C#中使用以下命令找到它:

AutomationElement ae = root.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "Database"), new PropertyCondition(AutomationElement.LocalizedControlTypeProperty, "edit"));

事实上,我能找到它的唯一方法是通过以下命令(在树后面):

AutomationElement ae = root.FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[2]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[2]
                    .FindAll(TreeScope.Children, Condition.TrueCondition)[0];

不幸的是,当我尝试编辑该值时,我收到一条错误消息,指出所选元素是只读的。但是,该元素实际上不是只读的。此外,该元素没有它应具有的automationId。使用UIAutomation查看时,树中的所有元素都没有AutomationId。

我尝试自动化的应用程序是专有应用程序,这是我第一次遇到此问题。我不确定是什么原因造成这种情况,我可以调查什么?

编辑:就像更新一样,我能够使用root.FindAll(TreeScope.Descendants,Condition.TrueCondition)中的索引成功找到所需的元素。

但是,我有以下代码:

        cachedElement = findAll[index];
        Console.Write("cachedelement : "); cachedElement.ToConsole();           
        return 0;

如果我只是让程序运行,它会在尝试将文本写入文本字段时失败。此外,它还显示所选元素没有属性(在cachedelement.ToConsole期间)。

有趣的是,如果我在返回0时设置断点; (或使用System.Diagnostics.Debugger.Break()),cachedElement.ToConsole()将LCT输出为“edit”(仍然没有automationId),并将文本正确写入文本字段。为什么我觉得这很有趣,就是在调用ToConsole之后设置了断点。它根本不应该对正在运行的代码产生影响。

1 个答案:

答案 0 :(得分:0)

根据您的第二个代码示例,您要查找的元素嵌套在树的相当远的位置,因此第一个代码示例永远不会找到该元素,因为它只查看桌面的子代。如果要从根节点查找元素,则需要使用TreeScope.Descendants作为树视图。我不建议使用后代,因为它会很慢,而且很可能在从根元素使用时会导致stack overflow

在最坏的情况下,我使用来自根元素的子作用域为我的窗口执行FindFirst,然后使用应用程序根目录中的后代。这仅适用于具有琐碎用户界面的小型应用程序。如果你有一些复杂的东西,比如带有单元格的网格,我建议使用带有子作用域的FindFirst一直到你正在寻找的元素,类似于你使用find all的方式。

如果您可以发布用于编辑元素的代码,我可以使用有关如何编辑特定于您的情况的控件的信息来更新此答案。一般情况下,如何编辑文本框控件将是使用ValuePattern这样的。{/ p>

  public void SetValue(AutomationElement element, string text)
  {
        var valuePattern = (ValuePattern) element.GetCurrentPattern(ValuePattern.Pattern);
        valuePattern.SetValue(text);
  }

希望这有帮助。