UIACOMWrapper:删除AutomationEventHandler时出现InvalidOperationException

时间:2017-07-14 10:05:25

标签: c# ui-automation microsoft-ui-automation

我使用下一个代码等待窗口打开:

  Automation.AddAutomationEventHandler(
    WindowPattern.WindowOpenedEvent,
    AutomationElement.RootElement,
    TreeScope.Children,
    (sender, e) =>
    {
      var element = sender as AutomationElement;
      if (element.Current.Name != rolesFormTitle)
        return;

      Automation.RemoveAllEventHandlers();
      SelectRoleOpenMainForm();
    });

添加对UIAComWrapper v1.1.0.14的引用(使用Nuget)后,我开始得到此异常(UIAComWrapper的源代码):

enter image description here

内部异常为空。 Factory.RemoveAllEventHandlers();

也出现了同样的异常

我应该以某种方式准备某个物体的状态吗?

UPDATE1:

堆栈追踪:

at UIAutomationClient.CUIAutomation8Class.RemoveAutomationEventHandler(Int32 eventId, IUIAutomationElement element, IUIAutomationEventHandler handler)
at System.Windows.Automation.Automation.RemoveAutomationEventHandler(AutomationEvent eventId, AutomationElement element, AutomationEventHandler eventHandler) in Automation.cs: line 239

Automation.cs的源代码(github):

    public static void RemoveAutomationEventHandler(AutomationEvent eventId, AutomationElement element, AutomationEventHandler eventHandler)
    {
        Utility.ValidateArgumentNonNull(element, "element");
        Utility.ValidateArgumentNonNull(eventHandler, "eventHandler");
        Utility.ValidateArgument(eventId != AutomationElement.AutomationFocusChangedEvent, "Use FocusChange notification instead");
        Utility.ValidateArgument(eventId != AutomationElement.StructureChangedEvent, "Use StructureChange notification instead");
        Utility.ValidateArgument(eventId != AutomationElement.AutomationPropertyChangedEvent, "Use PropertyChange notification instead");

        try
        {
            BasicEventListener listener = (BasicEventListener)ClientEventList.Remove(eventId, element, eventHandler);
            Factory.RemoveAutomationEventHandler(eventId.Id, element.NativeElement, listener);  // line 239
        }
        catch (System.Runtime.InteropServices.COMException e)
        {
            Exception newEx; if (Utility.ConvertException(e, out newEx)) { throw newEx; } else { throw; }
        }
    }

UPDATE2:

源代码:

    private void Form1_Load(object send, EventArgs ev)
    {
        Process.Start("calc");

        Automation.AddAutomationEventHandler(
            WindowPattern.WindowOpenedEvent,
            AutomationElement.RootElement,
            TreeScope.Children, (sender, e) =>
            {
                var element = sender as AutomationElement;
                if (!element.Current.Name.StartsWith("Calculator"))
                    return;

                Automation.RemoveAllEventHandlers();
                MessageBox.Show("BINGO!");
            });
        }

我从未看到过“BINGO!”的消息。它挂起在Automation.RemoveAllEventHandlers();

enter image description here

UPDATE3:

仍然挂起:

    private void Form1_Load(object send, EventArgs ev)
    {
        Process.Start("calc");

        Automation.AddAutomationEventHandler(
            WindowPattern.WindowOpenedEvent,
            AutomationElement.RootElement,
            TreeScope.Children, (sender, e) =>
            {
                var element = sender as AutomationElement;
                if (!element.Current.Name.StartsWith("Calculator"))
                    return;

                this.Invoke(new Action(() => RemoveTry()));
            });
    }

    private void RemoveTry()
    {
        Automation.RemoveAllEventHandlers(); // reachable
        MessageBox.Show("BINGO!");  // unreachable
    }

线程窗口:

Threads

解决方案:

请查看有关找到的解决方案的评论。

0 个答案:

没有答案