Suppose I'm implementing some UIA pattern in my custom control. Say, TablePattern
. Existing implementations return null if anything went wrong. But it is not very convenient to debug. I might have more of a context in the automation peer. For example, for GetItem(int row, int column)
I might say that provided arguments are out of bounds rather than just return null.
If I throw an exception from automation peer - on the UIA client side I get TargetInvocationException
from IUIAutomationPatternInstance
object without any details (InnerException property is null).
Is there a way to make UIA to pass error with some additional information from UIA-server side to UIA-client side?
UPD: After some investigation and comparison with example @SimonMourier provided in comments I found that TargetInvocationException
was my fault. Fixed it here.
Now I'm getting correct exception type, but only a standard exception message. For IndexOutBoundsException
it is "Index was outside the bounds of the array." regardless of what I've been trying to put in exception on UIA server side.
The difference is that I'm trying to call UIA method not through standard managed UIAutomationClient, but with my own code all the way down to COM call (standard managed library doesn't support custom UIA patterns which I'd like to use). Standard library passes exception messages just fine. I've tried to track what the difference is and found the following:
- Standard managed library makes call to P/Invoke through InternallCall here via method defined as
private static extern int RawGridPattern_GetItem(SafePatternHandle hobj, int row, int column, out SafeNodeHandle pResult);
. It returns HRESULT, which is handled byCheckError
method via call toMarshal.ThrowExceptionForHR(hr);
. At this point exception with correct message appears as was thrown on UIA server side. - UIAComWrapper which I use does seemingly same COM call defined in
c:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include\UIAutomationClient.idl
asHRESULT GetItem ([in] int row, [in] int column, [out, retval] IUIAutomationElement ** element );
. To my understanding of COM Interop, rewriting return value mechanism automatically checks HRESULT, throws an exception if necessary and returnout result
argument otherwise. It really does except that exception message does not get translated for some reason.
To reproduce the issue you can try this project. Files in lib folder were built from this repository. If ConsoleApplication1 references UIAComWrapper library - exception comes with default message. If you change reference to use standard UIAutomationClient instead - it receives custom one.