Как пройти все дочерние элементы программы
Я хочу построить дерево элементов пользовательского интерфейса, которые присутствуют в приложении. Я пытаюсь использовать 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}
).