Мы используем среду UIAutomation Microsoft для разработки клиента, который отслеживает события конкретного приложения и реагирует на них по-разному. Мы начали с управляемой версии фреймворка, но из-за проблем с задержкой переместились в родную версию, завернутую в UIACOMWrapper. После дополнительных проблем с производительностью внутри нашего (массивного) WPF-приложения мы решили перенести его в отдельное приложение терминала (перенос событий в наше приложение WPF через UDP), который, казалось, исправить все проблемы с производительностью. Единственная проблема заключается в том, что каждые несколько минут события для TabSelection, StructureChanged, WindowOpened и WindowClosed перестают захватываться в течение нескольких минут. Неожиданно события PropertyChanged все еще принимаются и обрабатываются, когда это происходит. Я отправлю соответствующий код нашего монитора событий, но это, вероятно, не имеет значения, поскольку мы видели подобное поведение при использовании собственной утилиты AccEvent от Microsoft. Я не могу опубликовать код контролируемого приложения, так как он является конфиденциальным и конфиденциальным, я могу сказать, что это приложение WinForms, в котором размещены окна WPF, а также довольно массивные. Кто-нибудь видел такое поведение при работе с инфраструктурой автоматизации пользовательского интерфейса? Спасибо за ваше время.События автоматизации пользовательского интерфейса перестают приниматься после мониторинга приложения и затем через некоторое время перезапускаются
Вот код монитор (я знаю, что обработка событий на резьбе UI Automation здесь, но сдвинув его к выделенной теме ничего не меняет):
public void registerHandlers()
{
//Register on structure changed and window opened events
System.Windows.Automation.Automation.AddStructureChangedEventHandler(
this.getMsAutomationElement(), System.Windows.Automation.TreeScope.Subtree, this.handleStructureChanged);
System.Windows.Automation.Automation.AddAutomationEventHandler(
System.Windows.Automation.WindowPattern.WindowOpenedEvent,
this.getMsAutomationElement(),
System.Windows.Automation.TreeScope.Subtree,
this.handleWindowOpened);
System.Windows.Automation.Automation.AddAutomationEventHandler(
System.Windows.Automation.WindowPattern.WindowClosedEvent,
System.Windows.Automation.AutomationElement.RootElement,
System.Windows.Automation.TreeScope.Subtree,
this.handleWindowClosed);
this.registerValueChanged();
this.registerTextNameChange();
this.registerTabSelected();
this.registerRangeValueChanged();
}
private void registerRangeValueChanged()
{
if (this.getMsAutomationElement() != null)
{
System.Windows.Automation.Automation.AddAutomationPropertyChangedEventHandler(
this.getMsAutomationElement(),
System.Windows.Automation.TreeScope.Subtree, this.handlePropertyChange,
System.Windows.Automation.RangeValuePattern.ValueProperty);
}
}
private void unregisterRangeValueChanged()
{
System.Windows.Automation.Automation.RemoveAutomationPropertyChangedEventHandler(
this.getMsAutomationElement(),
this.handlePropertyChange);
}
private void registerValueChanged()
{
if (this.getMsAutomationElement() != null)
{
System.Windows.Automation.Automation.AddAutomationPropertyChangedEventHandler(
this.getMsAutomationElement(),
System.Windows.Automation.TreeScope.Subtree, this.handlePropertyChange,
System.Windows.Automation.ValuePattern.ValueProperty);
}
}
private void unregisterValueChanged()
{
System.Windows.Automation.Automation.RemoveAutomationPropertyChangedEventHandler(
this.getMsAutomationElement(),
this.handlePropertyChange);
}
private void registerTextNameChange()
{
if (this.getMsAutomationElement() != null)
{
System.Windows.Automation.Automation.AddAutomationPropertyChangedEventHandler(
this.getMsAutomationElement(),
System.Windows.Automation.TreeScope.Subtree, this.handlePropertyChange,
System.Windows.Automation.AutomationElement.NameProperty);
}
}
private void unregisterTextNameChange()
{
System.Windows.Automation.Automation.RemoveAutomationPropertyChangedEventHandler(
this.getMsAutomationElement(),
this.handlePropertyChange);
}
private void handleWindowOpened(object src, System.Windows.Automation.AutomationEventArgs e)
{
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine(DateTime.Now.ToShortTimeString() + " " + "Window opened:" + " " +
(src as System.Windows.Automation.AutomationElement).Current.Name);
System.Windows.Automation.AutomationElement element = src as System.Windows.Automation.AutomationElement;
//this.sendEventToPluginQueue(src, e, element.GetRuntimeId(), this.getAutomationParent(element).GetRuntimeId());
//Fill out the fields of the control added message
int[] parentId = this.getAutomationParent(element).GetRuntimeId();
this.copyToIcdArray(parentId,
this.protocol.getMessageSet().outgoing.ControlAddedMessage.Data.controlAdded.parentRuntimeId);
this.copyToIcdArray(element.GetRuntimeId(),
this.protocol.getMessageSet().outgoing.ControlAddedMessage.Data.controlAdded.runtimeId);
//Send the message using the protocol
this.protocol.send(this.protocol.getMessageSet().outgoing.ControlAddedMessage);
}
private void copyToIcdArray(int[] runtimeId, ICD.UI_AUTOMATION.RuntimeId icdRuntimeId)
{
icdRuntimeId.runtimeIdNumberOfItems.setVal((byte)runtimeId.Count());
for (int i = 0; i < runtimeId.Count(); i++)
{
icdRuntimeId.runtimeIdArray.getElement(i).setVal(runtimeId[i]);
}
}
private void handleWindowClosed(object src, System.Windows.Automation.AutomationEventArgs e)
{
if (src != null)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(DateTime.Now.ToShortTimeString() + " " + "Window closed:" + " " +
(src as System.Windows.Automation.AutomationElement).GetRuntimeId().ToString());
System.Windows.Automation.AutomationElement element = src as System.Windows.Automation.AutomationElement;
this.copyToIcdArray(element.GetRuntimeId(),
this.protocol.getMessageSet().outgoing.ControlRemovedMessage.Data.controlRemoved.runtimeId);
//Send the message using the protocol
this.protocol.send(this.protocol.getMessageSet().outgoing.ControlRemovedMessage);
//this.sendEventToPluginQueue(src, e, element.GetRuntimeId());
}
}
EDIT: Я забыл упомянуть, что я сильно подозревают, что проблема в том, что один из потоков обработчика событий UI-Automation застрял как-то. Причина, по которой я верю в это, заключается в том, что когда проблема возникла на моем мониторе, я начал экземпляр AccEvent и получил все отсутствующие события, которые мой монитор не получал. Это означает, что события запускаются, но не передаются на мой монитор.
EDIT2: Я забыл упомянуть, что это происходит в Windows 8 с конкретным целевым приложением, я не видел этого явления на своей машине Windows 7 с другими приложениями. Еще одна интересная вещь заключается в том, что это происходит периодически более или менее, но независимо от того, когда я подписываюсь на события, т. Е. Это может произойти почти сразу после подписки, но затем требуется несколько минут для повторной регистрации.
Не имея рамки UIAutomation знания, я хочу высказать некоторые очевидные вещи: Вы проверить eventlogs из машин, участвующих (тайм-ауты, stackoverflows и т.д.). Вы просматривали ошибки привязки WPF во время выполнения (например, в области вывода в VS (включить трассировку WPF), совпадают ли они с отсутствующими событиями? –
Можете ли вы добавить [logging] (https://msdn.microsoft.com/en -us/library/windows/desktop/jj160543 (v = vs.85) .aspx) к событию, которое вы подозреваете. Как долго длится каждый тест для запуска примерно? 7 минут точно или переменно на минуту или две? у него есть возможность делать скриншоты? Это машина, посвященная автоматизации ui? – lloyd
@o_weisman любой шанс, что у вас есть понимание на http://stackoverflow.com/questions/32540442/when-i-try-to-use-ui- 0: – tofutim