Это метод автоматизации пользовательского интерфейса, который может обнаружить событие «Открытое окно» в любом месте системы, идентифицировать окно по тексту одного из его дочерних элементов и закрыть окно после положительной идентификации.
Обнаружение инициализируется с использованием Automation.AddAutomationEventHandler с WindowPattern.WindowOpenedEvent и параметром элемента автоматизации, установленным в AutomationElement.RootElement , который не имеетдругих предков, идентифицирует весь рабочий стол (любое окно).
Класс WindowWatcher
предоставляет открытый метод (WatchWindowBySubElementText
), который позволяет указывать текст, содержащийся в одном из вложенных элементов только что открытого окна.Если указанный текст найден, метод закрывает окно и уведомляет об операции с помощью пользовательского обработчика событий, который подписчик может использовать для определения того, что наблюдаемое окно было обнаружено и закрыто.
Пример использования с использованием текстовой строки, указанной в вопросе:
WindowWatcher watcher = new WindowWatcher();
watcher.ElementFound += (obj, evt) => { MessageBox.Show("Found and Closed!"); };
watcher.WatchWindowBySubElementText("Original message");
WindowWatcher
class:
Для этого класса требуется ProjectСсылка на эти сборки:
UIAutomationClient
UIAutomationTypes
Обратите внимание, что при идентификации событие класса удаляет AutomationОбработчик событий перед уведомлением подписчиков.Это всего лишь пример: он указывает, что обработчики должны быть удалены в какой-то момент.Класс может реализовать IDisposable
и удалить обработчик (и) при утилизации.
EDIT :
Изменено условие, которое не учитывает окно, созданное втекущий Процесс:
if (element is null || element.Current.ProcessId != Process.GetCurrentProcess().Id)
Как отметил Ахмед Абдельхамид в комментариях , он накладывает ограничение, которое, вероятно, не является необходимым: Dialod также может принадлежать текущему Процессу.Я оставил там только null
чек.
using System;
using System.Diagnostics;
using System.Windows.Automation;
public class WindowWatcher
{
public delegate void ElementFoundEventHandler(object sender, EventArgs e);
public event ElementFoundEventHandler ElementFound;
public WindowWatcher() { }
public void WatchWindowBySubElementText(string ElementText) =>
Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent,
AutomationElement.RootElement, TreeScope.Subtree, (UIElm, evt) =>
{
AutomationElement element = UIElm as AutomationElement;
if (element is null) return;
AutomationElement childElm = element.FindFirst(TreeScope.Children,
new PropertyCondition(AutomationElement.NameProperty, ElementText));
if (childElm != null)
{
(element.GetCurrentPattern(WindowPattern.Pattern) as WindowPattern).Close();
this.OnElementFound(new EventArgs());
}
});
public void OnElementFound(EventArgs e)
{
Automation.RemoveAllEventHandlers();
ElementFound?.Invoke(this, e);
}
}