C#中实现IUIAutomationElement到WinRT AutomationElement的映射方法
将COM版IUIAutomationElement转换为WinRT版AutomationElement的解决方案
在C#中,COM接口IUIAutomationElement和WinRT的AutomationElement分属不同类型系统,无法直接传入AutomationRemoteOperation.ImportElement方法。你需要通过COM指针完成跨类型转换,具体步骤如下:
- 提取COM对象的底层指针
使用Marshal.GetIUnknownForObject方法从IUIAutomationElement实例中获取COM指针。 - 通过指针构造WinRT AutomationElement
调用WinRT API的AutomationElement.FromAbi静态方法,将指针转换为AutomationElement实例。 - 释放COM指针避免内存泄漏
转换完成后,必须调用Marshal.Release释放之前获取的COM指针。
完整代码示例:
using System; using System.Diagnostics; using System.Runtime.InteropServices; using Windows.UI.Xaml.Automation; using Windows.UI.UIAutomation.Core; // 原有进程与COM元素获取逻辑 var processes = Process.GetProcessesByName("myprocess"); var process = processes.FirstOrDefault(p => p.MainWindowHandle != IntPtr.Zero); Interop.UIAutomationClient.IUIAutomation automation = new Interop.UIAutomationClient.CUIAutomation(); Interop.UIAutomationClient.IUIAutomationElement automationElement = automation.ElementFromHandle(process.MainWindowHandle); // 核心转换逻辑 IntPtr elementPtr = Marshal.GetIUnknownForObject(automationElement); try { AutomationElement winrtElement = AutomationElement.FromAbi(elementPtr); AutomationRemoteOperation op = new AutomationRemoteOperation(); op.ImportElement(winrtElement); // 可正常调用 } finally { Marshal.Release(elementPtr); // 必须释放指针,防止内存泄漏 }
注意事项
- 确保项目已引用
Windows.UI.UIAutomation.Core和Windows.UI.Xaml.Automation相关的WinRT SDK或NuGet包。 FromAbi方法要求指针指向有效的IUIAutomationElementCOM实例,否则会抛出异常。- 必须在
finally块中释放COM指针,即使转换过程中出现异常也能保证资源回收。
内容的提问来源于stack exchange,提问作者vibhu
相关产品推荐
相关产品推荐

