当只需要几个方法时,有什么方法可以避免创建巨大的 C# COM 接口包装器?

发布于 2024-09-01 19:19:20 字数 766 浏览 6 评论 0原文

大家好,

我正在开发一个 C# 程序,需要能够获取 Windows 7 资源管理器的新 ItemsView 控件中的热门项目的索引。幸运的是,Microsoft 提供了一种方法通过 UI 自动化,通过查询控件的自定义属性来执行此操作。

不幸的是,System.Windows.Automation命名空间莫名其妙地似乎没有提供查询自定义属性的方法!这让我不得不完全放弃 C# Automation 命名空间并仅使用非托管 COM 版本。一种方法是将所有自动化代码放入单独的 C++/CLI 模块中,并从我的 C# 应用程序中调用它。但是,如果可能的话,我想避免使用此选项,因为它会向我的项目添加更多文件,并且我必须担心 32/64 位问题等。

另一种选择是利用 ComImport 属性来声明相关接口并通过 COM 互操作完成所有操作。这就是我想做的。然而,相关的接口,例如 IUIAutomation 和 IUIAutomationElement,非常巨大。它们总共有数百个方法,并引用了大量的接口(我想我也必须声明这些接口),几乎所有这些我都永远不会使用。我认为 UI 自动化接口也没有在任何类型库中声明,因此我无法使用 TLBIMP。

有什么方法可以避免手动将大量方法签名转换为 C#,而只声明我实际需要的十个左右方法?我看到 C# 4.0 添加了一个新的“动态”类型,旨在简化 COM 互操作;这与我的问题有关吗?

谢谢

Greetings all,

I’m working on a C# program that requires being able to get the index of the hot item in Windows 7 Explorer’s new ItemsView control. Fortunately, Microsoft has provided a way to do this through UI Automation, by querying custom properties of the control.

Unfortunately, the System.Windows.Automation namespace inexplicably does not seem to provide a way to query custom properties! This leaves me with the undesirable position of having to completely ditch the C# Automation namespace and use only the unmanaged COM version. One way to do it would be to put all the Automation code in a separate C++/CLI module and call it from my C# application. However, I would like to avoid this option if possible, as it adds more files to my project, and I’d have to worry about 32/64-bit problems and such.

The other option is to make use of the ComImport attribute to declare the relevant interfaces and do everything through COM-interop. This is what I would like to do. However, the relevant interfaces, such as IUIAutomation and IUIAutomationElement, are FREAKING HUGE. They have hundreds of methods in total, and reference tons and tons of interfaces (which I assume I would have to also declare), almost all of which I will never ever use. I don’t think the UI Automation interfaces are declared in any Type Library either, so I can’t use TLBIMP.

Is there any way I can avoid having to manually translate a bajillion method signatures into C# and instead only declare the ten or so methods I actually need? I see that C# 4.0 added a new “dynamic” type that is supposed to ease COM interop; is that at all relevant to my problem?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

阿楠 2024-09-08 19:19:20

最重要的事情(从从 C# 调用 COM 方法的角度来看)是方法以正确的顺序出现在界面中。如果您不使用方法,则可以将其声明为 void 并且不会发生任何不好的事情(除非您实际调用它!)。这使您不必计算出正确的签名并定义所有其他类型等。例如,

[ComImport, Guid("30cbe57d-d9d0-452a-ab13-7ac5ac4825ee"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IUIAutomation
{
    void CompareElements();
    void CompareRuntimeIds();
    void GetRootElement();
    // 50 or so other methods...
    // ... define only the signatures for the ones you actually need
}

方法的定义顺序应与 UIAutomationClient.h(在 Windows SDK 中)中出现的顺序完全相同。

The most important thing (from the perspective of calling a COM method from C#) is that the methods appear in the interface in the right order. If you're not using a method, you can just declare it as void and nothing bad will happen (unless you actually call it!). This saves you from having to work out the correct signatures and define all the other types, etc. For example,

[ComImport, Guid("30cbe57d-d9d0-452a-ab13-7ac5ac4825ee"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IUIAutomation
{
    void CompareElements();
    void CompareRuntimeIds();
    void GetRootElement();
    // 50 or so other methods...
    // ... define only the signatures for the ones you actually need
}

The methods should be defined in exactly the same order they appear in UIAutomationClient.h (in the Windows SDK).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文