如何在C#中使用IUIAutomation :: ElementFromIAccessible方法?

时间:2016-07-06 06:57:33

标签: c# c++ microsoft-ui-automation

我尝试通过以下方法使用ElementFromIAccessible方法:

 System.Windows.Automation;
 ...
 [DllImport("UIAutomationClient.dll")]
    public static extern int ElementFromIAccessible(
        IAccessible accessible,
        int childId,
        [In, Out, MarshalAs(UnmanagedType.IUnknown)] ref AutomationElement element);

其中AutomationElement来自System.Windows.Automation

当我尝试称之为:

 Win32.ElementFromIAccessible(this.Accessible, 0, ref automaitonElement);

失败了

  

“System.Runtime.InteropServices.MarshalDirectiveException”“无法执行   pack参数#3“

如何正确映射?

1 个答案:

答案 0 :(得分:2)

<强> TL; DR; 本质上它失败了,因为你试图p调用一个不存在的本机方法,并且你试图在COM库上使用p-invoke。 COM无论如何(除了DllRegisterServerDllRegisterServer之外)DLL的导出表中都没有列表类方法。 UIAutomationClient.dll 中没有名为ElementFromIAccessible()的功能。但是有一个接口成员。

  

如何在C#中使用IUIAutomation :: ElementFromIAccessible方法?

IUIAutomation等是COM类型,因此不应使用p-invoke。相反,你应该使用COM互操作。

首先,在您的项目中添加一个COM引用到UIAutomationClient v1.0:

enter image description here

然后,使用如下代码,您可以创建CUIAutomation的实例并调用IUIAutomation.ElementFromIAccessible()方法:

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);
  

如何正确映射?

您无法将IUIAutomationElement投放到System.Windows.Automation中的类型,因为:

  1. 一个是COM类型,另一个是托管
  2. IUIAutomationElement未在System.Windows.Automation
  3. 中定义
  4. System.Windows.Automation.AutomationElement未实现IUIAutomationElement(后者无论如何都是COM类型)
  5. 您应该使用COM UIA并避免混合和匹配。此外,根据doco,COM UIA具有比托管库更多的功能。

    动态

    您可以使用.NET 4的动态COM对象调用功能,使用IDispatch,如:

    dynamic element = automation.ElementFromIAccessible (...);
    string name = element.accName;
    

    ...然而,自动完成不会起作用。由于您已经可以通过COM引用访问UIA类型库,它提供了强大的类型,因此这种替代方案的用处不大。