5

I am trying to click a button using invoke pattern.

InvokePattern ipAddMPButton = (InvokePattern)aeAddMPButton.GetCurrentPattern(InvokePattern.Pattern);
        try
        {
            ipAddMPButton .Invoke();
        }
        catch (System.Runtime.InteropServices.COMException e)
        {
            // TODO
        }

It throws COMException and I can't figure out why?

When I run this code, the button is actually pressed and the functionality works well. But then it just stops for some time, and throws this exception.

HasnainMamdani
  • 134
  • 2
  • 11
  • Also, if its.actually performing operation, then why worry just catch the exception and proceed with flow as is....This is just in case where you don't get a rock solid solution – Ronak Agrawal Dec 01 '14 at 06:26
  • I actually have the same behavior in an application I am trying to manipulate with UIAutomation. In my case, this happens with Winforms buttons that open Winforms dialogs (I believe they may be message boxes). The calling thread gets stuck for exactly 1 minute and then throws the exception "0x80040201 - An event was unable to invoke any of the subscribers." I have tested these buttons with the Inspect.exe tool and while I can't see the exception, it exhibits similar behavior, namely freezes for a minute after calling Invoke (although the invocation is performed correctly). – o_weisman Feb 17 '16 at 06:59
  • Is it a standard Winforms Button or is it a special thing? Do you have any reproducing code? 0x80040201 is UIA_E_ELEMENTNOTAVAILABLE, so, it may be a racing condition issue, like some code (in the app) destroys the button too early before all communications are over between your UIA app and the target app. – Simon Mourier Feb 19 '16 at 15:57
  • @SimonMourier Actually the button is still visible behind the newly opened dialog box so I'm guessing it is not destroyed, however, I suspect that because this is a modal dialog box, the rest of the application is not pumping messages and can not be interacted with. Possibly it gets locked before it can return the result of the Click() call to the UIAutomation thread? – o_weisman Feb 21 '16 at 06:57
  • That's possible, yes. It could also change its parenting relation, which can also defeat some UIA inner workings. With UIA, nothing is guaranteed, since your code is interacting with "something" that was not specifically designed to interact with anything. If you own the target application though, it should be much easier. – Simon Mourier Feb 21 '16 at 10:08
  • I've managed to reproduce a similar behavior by just creating a Winforms application that has a single button. In the Click handler, I open a simple message box. When using UI Automation Click() on the button, it is clicked and the message box is opened, but my application is hung for a few seconds and then reports an error: Error HRESULT E_FAIL has been returned from a call to a COM component – o_weisman Feb 23 '16 at 08:37

2 Answers2

2

Actually I have found that this is already discussed here: https://social.msdn.microsoft.com/Forums/en-US/673bba3d-27b3-4374-b049-0d2e8ec5e462/hang-with-invokepattern-invoke-in-virtual-pc?forum=windowsaccessibilityandautomation . To summarize, Winforms opening of modal dialog does not play nicely with UIAutomation as it does not return from the Invoke command and only creates the modal dialog which of course prevents it from completing the operation. The proposed solution is to spawn a background thread and activate Invoke (or any other operation) from that thread. I also suggest enforcing some kind of timeout for the completion of the operation as it can be lengthy in some circumstances.

o_weisman
  • 804
  • 7
  • 19
1

Try checking aeAddMPButton.GetAllSupportedPatterns() and then try invoking then..

Ronak Agrawal
  • 1,006
  • 1
  • 19
  • 48
  • Does this have any rational explanation or is it just a "knock on wood" sort of charm? – o_weisman Feb 23 '16 at 08:54
  • A call to GetAllSupportedPatterns() returns all the supported patterns for the element. The above exception is thrown when the exception is not supported, or (in rare cases) patterns are not loaded. The generated list makes sure that you traverse through loaded/supported patterns only, thus avoiding the possibility of raising invalid pattern exception – Ronak Agrawal Feb 24 '16 at 09:39
  • You are correct, but I believe that in this instance, the problem is not an unsupported pattern but rather a case of the button not returning from the Invoke call as I quoted in my answer below. Had the pattern not been supported, the exception would not have been caught as the GetCurrentPattern would have thrown the exception and it is outside of the try block. – o_weisman Feb 24 '16 at 09:53
  • Makes sense. Thanks for sharing this! – Ronak Agrawal Feb 24 '16 at 10:07