如何在 C# 中使用 IUIAutomation::ElementFromIAccessible 方法?
How to use IUIAutomation::ElementFromIAccessible method in C#?
我尝试通过以下方式使用 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" "Unable to
pack parameter #3"
如何正确映射它?
TL; DR; 本质上它失败了,因为您正在尝试 p-invoke 一个不存在的本机方法,并且您正在尝试在 COM 库上使用 p-invoke。无论如何,COM 不会(除了 DllRegisterServer
和 DllRegisterServer
)在 DLL 的导出 table 中列出 class 方法。在UIAutomationClient.dll中没有ElementFromIAccessible()
这样的函数。但是有一个接口成员。
How to use IUIAutomation::ElementFromIAccessible method in C#?
IUIAutomation
等是 COM 类型,因此您不应该 使用 p-invoke。相反,您应该使用 COM 互操作。
首先,在您的项目中添加对 UIAutomationClient v1.0 的 COM 引用:
然后,使用如下代码,您为 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);
How Do I map it right way?
您不能将 IUIAutomationElement
转换为 System.Windows.Automation
中的类型,因为:
- 一个是 COM 类型,另一个是托管类型
IUIAutomationElement
未在 System.Windows.Automation
中定义
System.Windows.Automation.AutomationElement
没有实现IUIAutomationElement
(后者反正是COM类型)
你应该只使用 COM UIA,不要混合和匹配。此外,根据 doco,COM UIA 比托管库具有更多功能。
动态
您可以通过 IDispatch 使用 .NET 4 的动态 COM 对象调用功能,例如:
dynamic element = automation.ElementFromIAccessible (...);
string name = element.accName;
...但是自动完成将不起作用。由于您已经可以通过提供强类型的 COM 参考访问 UIA 类型库,因此这种替代方法的用处不大。
我尝试通过以下方式使用 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" "Unable to pack parameter #3"
如何正确映射它?
TL; DR; 本质上它失败了,因为您正在尝试 p-invoke 一个不存在的本机方法,并且您正在尝试在 COM 库上使用 p-invoke。无论如何,COM 不会(除了 DllRegisterServer
和 DllRegisterServer
)在 DLL 的导出 table 中列出 class 方法。在UIAutomationClient.dll中没有ElementFromIAccessible()
这样的函数。但是有一个接口成员。
How to use IUIAutomation::ElementFromIAccessible method in C#?
IUIAutomation
等是 COM 类型,因此您不应该 使用 p-invoke。相反,您应该使用 COM 互操作。
首先,在您的项目中添加对 UIAutomationClient v1.0 的 COM 引用:
然后,使用如下代码,您为 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);
How Do I map it right way?
您不能将 IUIAutomationElement
转换为 System.Windows.Automation
中的类型,因为:
- 一个是 COM 类型,另一个是托管类型
IUIAutomationElement
未在System.Windows.Automation
中定义
System.Windows.Automation.AutomationElement
没有实现IUIAutomationElement
(后者反正是COM类型)
你应该只使用 COM UIA,不要混合和匹配。此外,根据 doco,COM UIA 比托管库具有更多功能。
动态
您可以通过 IDispatch 使用 .NET 4 的动态 COM 对象调用功能,例如:
dynamic element = automation.ElementFromIAccessible (...);
string name = element.accName;
...但是自动完成将不起作用。由于您已经可以通过提供强类型的 COM 参考访问 UIA 类型库,因此这种替代方法的用处不大。