C# 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

我们正在使用Microsoft的UIAutomation框架开发一个客户端,该客户端监视特定应用程序的事件,并以不同的方式响应这些事件。我们已经从框架的托管版本开始,但是由于延迟问题,我们转移到了包装在中的本机版本。在我们(大规模)WPF应用程序中出现更多性能问题后,我们决定将其移动到一个单独的终端应用程序(通过UDP将事件传输到我们的WPF应用程序),这似乎解决了所有性能问题。唯一的问题是,似乎每隔几分钟,TabSelection、StructureChanged、WindowOpen和WindowClosed的事件就会停止捕获几分钟。令人惊讶的是,在这种情况发生时,仍然会接收和处理PropertyChanged事件。我将发布事件监视器的相关代码,但这可能与我们在使用Microsoft自己的AccEvent实用程序时看到的类似行为无关。我不能发布受监控应用程序的代码,因为它也是专有的和机密的,我可以说它是一个WinForms应用程序,承载WPF窗口,而且相当庞大。 有人在使用UI自动化框架时见过这种行为吗? 谢谢你抽出时间

以下是监控代码(我知道事件处理在这里的UI自动化线程上,但将其移动到专用线程不会改变任何内容):

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);
}