0

I am trying to debug some scripts (that use Windows UI Automation support to identify GUI object) that I have developed and that are failing intermittently because they cannot find certain controls in the tree. I'm using also screenshots to check the state of the window that I'm testing and it seems that the controls are there in GUI, but my search inside the tree does not find them (even after a few seconds of sleep). When I use inspect.exe to check the tree, the objects are there.

Is there a way to dump that tree for later analysis? The only way I found until now is by crawling the whole tree recursively, but this is not feasible as it takes an awful lot of time.

Radu Enea
  • 27
  • 7
  • You're likely not taking advantage of caching. Can you post your code that's dumping the tree? – Eric Brown May 12 '14 at 18:49
  • Well, I don't have the code for dumping the tree. I tried a few weeks ago to crawl the tree, but it was just a quick look into it and dumped that piece of work. But if you're saying that caching might be helpful, I will try to investigate on this path. Thanks! – Radu Enea May 13 '14 at 09:06
  • 1
    You don't mention which language you're using, so I can't provide further guidance. – Eric Brown May 13 '14 at 16:37

1 Answers1

2

Here is my code:

public static string DumpUIATree(this AutomationElement element, bool dumpFullInfo = false)
{
  var s = element.Name() + " : " + element.ControlType().ProgrammaticName;
  DumpChildrenRecursively(element, 1, ref s, dumpFullInfo);
  return s;
}

private static List<AutomationElement> GetChildNodes(this AutomationElement automationElement)
{
  var children = new List<AutomationElement>();
  TreeWalker walker = TreeWalker.ControlViewWalker;
  AutomationElement child = walker.GetFirstChild(automationElement);
  while (child != null)
  {
    children.Add(child);
    child = walker.GetNextSibling(child);
  }
  return children;
}

private static void DumpChildrenRecursively(AutomationElement node, int level, ref string s, bool dumpFullInfo = false)
{
  var children = node.GetChildNodes();
  foreach (var child in children)
  {
    if (child != null)
    {
      for (int i = 0; i < level; i++)
        s += "-";
      s += " " + child.Name() + " : " + child.ControlType().ProgrammaticName + "\r\n";

      if (dumpFullInfo)
      {
        foreach (var prop in child.GetSupportedProperties())
        {
          s += "   > " + prop.ProgrammaticName + " = " + child.GetCurrentPropertyValue(prop) + "\r\n";
        }

        s += "\r\n";
      }

      DumpChildrenRecursively(child, level + 1, ref s, dumpFullInfo);
    }
  }
}
Ivan Shakhov
  • 1,299
  • 11
  • 12
  • At few places I needed to insert "Current", e.g. child.Current.Name instead of child.Name(), but in general it works. Thanks. – jing Dec 12 '16 at 17:30