0

I used the next code to wait for window opened:

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

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

After adding reference to UIAComWrapper v1.1.0.14 (using Nuget) I started getting this exception (source code of UIAComWrapper):

enter image description here

Inner exception is null. The same exception rises for Factory.RemoveAllEventHandlers();

Should I prepare the state of some object somehow?

UPDATE1:

Stack trace:

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

Source code of 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:

Source code:

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

I never see the message "BINGO!". It hangs on Automation.RemoveAllEventHandlers();

enter image description here

UPDATE3:

Still hangs:

    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 window:

Threads

SOLUTION FOUND:

Please, see comments for the solution found.

Taras Kozubski
  • 1,854
  • 1
  • 20
  • 33
  • 1
    Difficult to say w/o a full reproducting code and a full stack trace – Simon Mourier Jul 14 '17 at 12:49
  • Stack trace added – Taras Kozubski Jul 18 '17 at 07:40
  • 1
    It binds directly to this method: https://msdn.microsoft.com/en-us/library/windows/desktop/ee671557.aspx that could be a thread issue. Maybe you could also just ignore this error depending on your context – Simon Mourier Jul 18 '17 at 08:14
  • No, it just hangs on this line in case of ignoring error. – Taras Kozubski Jul 18 '17 at 08:18
  • My OS is Windows 8.0 with the latest updates – Taras Kozubski Jul 18 '17 at 09:19
  • 1
    I'm on Windows 10 and cannot reproduce with your code, however, like I said, the doc says you shouldn't use different thread to add or remove handle, and that's what you do because the Remove happens in another thread than the Add. – Simon Mourier Jul 18 '17 at 09:54
  • 1
    As Simon Mourier says and has already been stated, you should add and remove handlers of events on the same thread and NOT from your event handlers. Try passing the removal code to the same thread that added the event handler. This might fix the issue. – o_weisman Jul 18 '17 at 11:04
  • 1
    This smells heavily like a threading deadlock. Use the Debug > Windows > Threads window to see on what thread the event handler runs. Also look at what the main UI thread is doing. Expectation is that the event handler runs on that same UI thread, do make sure the Main() entrypoint of the program still has the [STAThread] attribute. – Hans Passant Jul 18 '17 at 11:38
  • @SimonMourier Still no luck. – Taras Kozubski Jul 18 '17 at 11:43
  • @o_weisman Please, see my code in UPDATE3. Still does not work – Taras Kozubski Jul 18 '17 at 11:44
  • 1
    Sure, Invoke() will hang for the exact same reason that RemoveAllEventHandlers() hangs. Never, never use Invoke when BeginInvoke can get the job done as well. And never use a band-aid over a bleeding wound, find the core problem. – Hans Passant Jul 18 '17 at 11:47
  • Thank you, guys! BeginInvoke() works just fine! ) How may I select all your answers as "BEST"? – Taras Kozubski Jul 18 '17 at 11:51
  • @SimonMourier Please, add an answer like "you shouldn't use different thread to add or remove handle" and I'll mark it as "Best" – Taras Kozubski Jul 18 '17 at 12:16
  • @HansPassant Please, create an answer similar to your comments, I'll mark it as "Best" (if it is possible to have two best answers) – Taras Kozubski Jul 18 '17 at 12:25

0 Answers0