Как пройти все дочерние элементы программы

Я хочу построить дерево элементов пользовательского интерфейса, которые присутствуют в приложении. Я пытаюсь использовать Microsoft UI Automation. Я могу получить доступ к рабочему столу путем доступа к AutomationElement.RootElement, но я не уверен, как получить доступ к приложению, которое выполняется на рабочем столе.

Основная цель - создать дерево пользовательского интерфейса целевого приложения, уже запущенного на рабочем столе. У меня нет доступа к коду целевого приложения.

Когда я пытаюсь бежать

foreach (var item in AutomationElement.RootElement.CachedChildren)
        {
            Console.WriteLine(item.ToString());
        }

Это дает мне фатальную ошибку: не удается получить свойство или элемент, который не кэшируется.

Пожалуйста, предложите, как лучше всего решить эту проблему.

1 ответ

Решение

Вы пытаетесь использовать функцию кэширования UIA, которая позволяет вам кэшировать AutomationElements и их свойства и улучшить производительность при доступе к ним. Это расширенная функция, очевидно, не связанная с вашим вопросом, так как сначала вам нужно получить AutomationElements из дерева пользовательского интерфейса.

Кроме того, ваш код, даже если бы он работал, не вернул бы все дерево, только дочерние элементы рабочего стола (в UIA "дочерние элементы" фактически означают элементы, находящиеся только в одной иерархии под конкретным элементом). Для навигации по дереву пользовательского интерфейса вам необходимо использовать TreeWalker учебный класс. На MSDN есть довольно хорошая документация, поэтому я советую вам сначала пойти туда, прежде чем начать его использовать.

Обратите внимание, что если вы хотите отобразить свое собственное приложение, а не все дерево пользовательского интерфейса, вам необходимо создать экземпляр TreeWalker объект с условием, которое возвратит главное окно вашего приложения.

Последнее замечание - звонок ToString() на AutomationElement не вернул бы ничего особенного. Если вы хотите получить имя элемента управления или любое другое свойство, вы можете использовать GetCurrentPropertyValue метод (или доступ Current.{PropertyName}).

Другие вопросы по тегам