8

I am developing an app in C++ that uses UIAutomation to receive notification of significant events related to user interaction. I have tried anevent handler by calling AddAutomationEventHandler to listened for window opened events, but I am having problems stopping the notification and cleaning up before exiting. If the user has launched certain applications, such as Firefox, the call to RemoveAutomationEventHandlerhangs. (Calling RemoveAllEventHandlers also hangs in this case.) Note that all calls to add or remove event handlers are done in the context of the same non-UI thread.

Note: I am seeing this behavior on Windows 7 and on Windows 8.

Any ideas on why this is happening or how to fix it? What makes the structure changed event different from all the others?

Wayne
  • 321
  • 1
  • 3
  • 7

1 Answers1

3

Window open/close events are implemented via the kernel WinEvent handlers; the structure change events involve the client app. Does your non-ui thread pump messages? UI Automation needs to pump messages to get cross-process communications working.

Eric Brown
  • 13,774
  • 7
  • 30
  • 71
  • 1
    Can you clarify a little more about the need to pump messages? Are you talking about Windows messages? How should one go about doing this and aren't all UiAutomation calls and events basically cross-process? – o_weisman Jul 13 '15 at 11:56
  • 1
    @o_weisman In particular, single-threaded apartment (STA) threads must pump windows messages in order to get incoming COM calls dispatched into the thread. If you have put your thread into the MTA (or you're using managed code, which is more or less the same thing), then incoming COM calls can be dispatched to any waiting thread in the MTA. And yes, most UI Automation calls and events are basically cross-process. – Eric Brown Jul 15 '15 at 03:23
  • 1
    Hi Eric, thanks for the response. Unlike the OP, I am developing using the managed C# libraries of UI Automation and still, I am experiencing similar hangs in RemoveAllEventHandlers at times. What's even more peculiar, I am seeing very long delays (in minutes) between opening of Winforms windows in the tested application and the calling of my UI Automation WindowOpened handler. Ever come across such behaviors? – o_weisman Jul 15 '15 at 05:56
  • 1
    @o_weisman 3 thoughts: 1) You're not using [Thread.SetApartmentState](https://msdn.microsoft.com/en-us/library/system.threading.thread.setapartmentstate(v=vs.110).aspx), are you? 2) Are you adding & removing your event handlers on the same MTA thread? 3) All UIA calls should be made from MTA (non-ui) threads. – Eric Brown Jul 16 '15 at 06:16
  • 1
    1) no but the thread is MTA 2) yes 3) they are . I am really stumped. Is the fact that the automated application Winforms with Wpf windows relevant at all? – o_weisman Jul 16 '15 at 08:08
  • @o_weisman Do you see the events delivered promptly via [AccEvent](https://msdn.microsoft.com/en-us/library/windows/desktop/dd317979(v=vs.85).aspx) - make sure you select the UIA events, not the MSAA events. If AccEvent is getting the events delivered promptly, then the next thing I would do is to make sure that your background threads aren't blocked on some long-running task. – Eric Brown Jul 16 '15 at 20:45
  • Yes AccEvent is getting the events just fine, but as far as I know it uses the unmanaged version of UIA. When I tried using that version (wrapped in a c# dll from codeplex) it responded better to events but had other issues namely a different automation tree where some combo boxes and spinners could not be accessed. – o_weisman Jul 18 '15 at 07:23
  • Update: we tried creating a simple c# terminal application that builds the automation tree for the tested app and listens to its events and we got interesting results. Winform windows open events that could be delivered up to ten minutes from the event are now between 9 and 15 seconds. Wpf windows open events that were previously delivered within 1-3 seconds are now caught between 10-20 seconds. Strangely, our simple terminal application uses the threads that call the event handlers to remove them, which is a big no-no I understand but seems to work better. – o_weisman Jul 18 '15 at 07:30
  • @o_weisman It seems you're using the old managed UI Automation classes. The problem with that is that code has notorious performance issues. It's also unmaintained, and isn't going to get those bugs resolved ever. I've been talking with the UI Automation developers, and their recommendation is to simply [create a wrapper around the (maintained) native libraries using tlbimp](https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/77a5394b-b5ac-44db-99f2-646743b25305/a-request-for-feedback-on-the-nativecode-ui-automation-api?forum=windowsaccessibilityandautomation). – Eric Brown Jul 22 '15 at 22:45
  • @o_weisman Guy Barker (one of the UI Automation devs) has a [set of samples](https://code.msdn.microsoft.com/site/search?f%5B0%5D.Type=User&f%5B0%5D.Value=Guy%20Barker%20MSFT.) using this approach. – Eric Brown Jul 22 '15 at 22:46
  • I've read Guy's blog a bit including some of the samples and also his claim that the managed version is being phased out not very subtly. I must say that it seems odd but I guess that's just the way the cookie crumbles. Thanks a bundle for all your time and help :) . Guess we'll have to give the native version another go eventually. – o_weisman Jul 23 '15 at 11:17