I've tried to use ElementFromIAccessible
method via:
System.Windows.Automation;
...
[DllImport("UIAutomationClient.dll")]
public static extern int ElementFromIAccessible(
IAccessible accessible,
int childId,
[In, Out, MarshalAs(UnmanagedType.IUnknown)] ref AutomationElement element);
where AutomationElement
is from System.Windows.Automation
.
And when I try to call it like:
Win32.ElementFromIAccessible(this.Accessible, 0, ref automaitonElement);
It fails with
"System.Runtime.InteropServices.MarshalDirectiveException" "Unable to pack parameter #3"
How Do I map it right way?
TL; DR; essentially it's failing because you are trying to p-invoke a non-existent native method and also that you are trying to use p-invoke on a COM library. COM does not (apart from DllRegisterServer
and DllRegisterServer
) list class methods in the DLL's export table anyway. There is no such function called ElementFromIAccessible()
in UIAutomationClient.dll. However there is a interface member.
How to use IUIAutomation::ElementFromIAccessible method in C#?
IUIAutomation
and the like are COM types so you should not be using p-invoke. Instead you should be using COM interop.
First, in your project add a COM reference to UIAutomationClient v1.0:
Then, using code like the following, you create an instance to CUIAutomation
and invoke the IUIAutomation.ElementFromIAccessible()
method:
CUIAutomation automation = new CUIAutomation();
IAccessible accessible = // you need to supply a value here
int childId = 0; // you need to supply a value here
IUIAutomationElement element = automation.ElementFromIAccessible(accessible, childId);
How Do I map it right way?
You can't cast IUIAutomationElement
to types in System.Windows.Automation
because:
IUIAutomationElement
is not defined in System.Windows.Automation
System.Windows.Automation.AutomationElement
does not realise IUIAutomationElement
(the latter is a COM type anyway) You should just use the COM UIA and refrain from mixing and matching. Also, according to the doco, COM UIA has more features than the managed library.
You could use .NET 4's features of dynamic COM object invokation using IDispatch like:
dynamic element = automation.ElementFromIAccessible (...);
string name = element.accName;
...however auto-complete won't work. Since you already have access to UIA type library via the COM Reference which does provide strong typing, such an alternative is somewhat less useful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With