C# UI自动化事件在监视应用程序一段时间后停止接收,然后在一段时间后重新启动
我们正在使用Microsoft的UIAutomation框架开发一个客户端,该客户端监视特定应用程序的事件,并以不同的方式响应这些事件。我们已经从框架的托管版本开始,但是由于延迟问题,我们转移到了包装在中的本机版本。在我们(大规模)WPF应用程序中出现更多性能问题后,我们决定将其移动到一个单独的终端应用程序(通过UDP将事件传输到我们的WPF应用程序),这似乎解决了所有性能问题。唯一的问题是,似乎每隔几分钟,TabSelection、StructureChanged、WindowOpen和WindowClosed的事件就会停止捕获几分钟。令人惊讶的是,在这种情况发生时,仍然会接收和处理PropertyChanged事件。我将发布事件监视器的相关代码,但这可能与我们在使用Microsoft自己的AccEvent实用程序时看到的类似行为无关。我不能发布受监控应用程序的代码,因为它也是专有的和机密的,我可以说它是一个WinForms应用程序,承载WPF窗口,而且相当庞大。 有人在使用UI自动化框架时见过这种行为吗? 谢谢你抽出时间 以下是监控代码(我知道事件处理在这里的UI自动化线程上,但将其移动到专用线程不会改变任何内容):C# UI自动化事件在监视应用程序一段时间后停止接收,然后在一段时间后重新启动,c#,ui-automation,wpf-4.0,microsoft-ui-automation,C#,Ui Automation,Wpf 4.0,Microsoft Ui Automation,我们正在使用Microsoft的UIAutomation框架开发一个客户端,该客户端监视特定应用程序的事件,并以不同的方式响应这些事件。我们已经从框架的托管版本开始,但是由于延迟问题,我们转移到了包装在中的本机版本。在我们(大规模)WPF应用程序中出现更多性能问题后,我们决定将其移动到一个单独的终端应用程序(通过UDP将事件传输到我们的WPF应用程序),这似乎解决了所有性能问题。唯一的问题是,似乎每隔几分钟,TabSelection、StructureChanged、WindowOpen和Win
public void registerHandlers()
{
//在结构更改和窗口打开事件上注册
System.Windows.Automation.Automation.AddStructureChangedEventHandler(
this.getmAutomationElement(),System.Windows.Automation.TreeScope.Subtree,this.handleStructureChanged);
System.Windows.Automation.Automation.AddAutomationEventHandler(
System.Windows.Automation.WindowPattern.WindowOpenedEvent,
此.getMsAutomationElement()文件,
System.Windows.Automation.TreeScope.Subtree,
这是我的手稿);
System.Windows.Automation.Automation.AddAutomationEventHandler(
System.Windows.Automation.WindowPattern.WindowClosedEvent,
System.Windows.Automation.AutomationElement.RootElement,
System.Windows.Automation.TreeScope.Subtree,
此项。手柄(关闭);
this.registerValueChanged();
this.registerTextNameChange();
this.registerAbselected();
this.registerRangeValueChanged();
}
private void registerRangeValueChanged()
{
if(this.getMsAutomationElement()!=null)
{
System.Windows.Automation.Automation.AddAutomationPropertyChangedEventHandler(
此.getMsAutomationElement()文件,
System.Windows.Automation.TreeScope.Subtree,this.handlePropertyChange,
System.Windows.Automation.RangeValuePattern.ValueProperty);
}
}
私有void unregisterRangeValueChanged()
{
System.Windows.Automation.Automation.RemoveAutomationPropertyChangedEventHandler(
此.getMsAutomationElement()文件,
这是一种新的方法;
}
私有无效registerValueChanged()
{
if(this.getMsAutomationElement()!=null)
{
System.Windows.Automation.Automation.AddAutomationPropertyChangedEventHandler(
此.getMsAutomationElement()文件,
System.Windows.Automation.TreeScope.Subtree,this.handlePropertyChange,
System.Windows.Automation.ValuePattern.ValueProperty);
}
}
private void unregisterValueChanged()
{
System.Windows.Automation.Automation.RemoveAutomationPropertyChangedEventHandler(
此.getMsAutomationElement()文件,
这是一种新的方法;
}
私有无效注册表TextNameChange()
{
if(this.getMsAutomationElement()!=null)
{
System.Windows.Automation.Automation.AddAutomationPropertyChangedEventHandler(
此.getMsAutomationElement()文件,
System.Windows.Automation.TreeScope.Subtree,this.handlePropertyChange,
System.Windows.Automation.AutomationElement.NameProperty);
}
}
私有void unregisterTextNameChange()
{
System.Windows.Automation.Automation.RemoveAutomationPropertyChangedEventHandler(
此.getMsAutomationElement()文件,
这是一种新的方法;
}
私有无效句柄已打开(对象src,System.Windows.Automation.AutomationEventArgs e)
{
Console.ForegroundColor=ConsoleColor.Pigenta;
Console.WriteLine(DateTime.Now.ToSortTimeString()+“”+”窗口打开:“+”
(src as System.Windows.Automation.AutomationElement.Current.Name);
System.Windows.Automation.AutomationElement元素=src as System.Windows.Automation.AutomationElement;
//this.sendEventToPluginQueue(src,e,element.GetRuntimeId(),this.getAutomationParent(element.GetRuntimeId());
//填写控件添加消息的字段
int[]parentId=this.getAutomationParent(元素).GetRuntimeId();
此.copyToIcdArray(parentId,
this.protocol.getMessageSet().outing.ControlAddedMessage.Data.controlAdded.parentRuntimeId);
this.copyToIcdArray(element.GetRuntimeId(),
this.protocol.getMessageSet().outing.ControlAddedMessage.Data.controlAdded.runtimeId);
//使用协议发送消息
this.protocol.send(this.protocol.getMessageSet().outing.ControlAddedMessage);
}
私有void copyToIcdArray(int[]runtimeId,ICD.UI\u AUTOMATION.runtimeId icdRuntimeId)
{
icdRuntimeId.runtimeIdNumberOfItems.setVal((字节)runtimeId.Count());
对于(int i=0;i 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());
}
}
IUIAutomation uiAutomation = new CUIAutomation8();
IUIAutomationElement rootElement = uiAutomation.GetRootElement();
uiAutomation.AddAutomationEventHandler(
20016, // UIA_Window_WindowOpenedEventId
rootElement,
TreeScope.TreeScope_Descendants,
null,
this);
public void HandleAutomationEvent(IUIAutomationElement sender, int eventId)
{
// Got a window opened event...
}
int propertyRuntimeId = 30000; // UIA_RuntimeIdPropertyId
IUIAutomationCacheRequest cacheRequestRuntimeId = uiAutomation.CreateCacheRequest();
cacheRequestRuntimeId.AddProperty(propertyRuntimeId);
uiAutomation.AddAutomationEventHandler(
20016, // UIA_Window_WindowOpenedEventId
rootElement,
TreeScope.TreeScope_Descendants,
cacheRequestRuntimeId,
this);
public void HandleAutomationEvent(IUIAutomationElement sender, int eventId)
{
// Got a window opened event...
// Get the RuntimeId from the source element. Because that data is cached with the
// event, we don't have to call back through UIA into the provider process here.
int[] runtimeId = sender.GetCachedPropertyValue(propertyRuntimeId);
}