VS2017 引用管理器在 COM 选项卡上不显示托管 COM 组件

VS2017 Reference Manager does not show Managed COM components on the COM tab

我有许多已构建并注册为 COM 组件的 C# 程序集。从非托管代码(Windows 的 Fujitsu NetCOBOL)调用时,它们工作得非常好,而且从 C# 调用 COBOL COM 组件时我也没有困难。非托管COM组件出现在VS 2017 Reference Manager COM选项卡中,VS 2017生成Interop,一切都很好。

但是,如果我尝试将其中一个托管 COM 组件与托管代码(C# .exe)结合使用,VS 2017 引用管理器不会显示 .DLL 的条目。相反,它显示组件的描述而不是名称,它指向我构建原始组件时生成的 .TLB。如果我 select 该引用,会发生这种情况:

如果我浏览并找到 .DLL,则添加引用正常,但它会强制我“复制本地”,并且我会获得与我的可执行文件一起部署的 .DLL 的副本。

如果我尝试将其设置为 false,并嵌入类型,它将无法构建,并且我收到一条关于未设置一些晦涩属性的消息...

如果我按所示构建它,它会部署并完美运行,但我将 COM 组件 .dll 的副本添加到我部署的每个可执行文件中。这种做法破坏了 COM 组件的对象,其中一份代码副本在用户之间共享。我多年来一直使用 COM 和非托管代码,从来没有遇到过任何问题。使用托管代码是否需要不同的理解?

我花了很多时间阅读有关 COM 和 interOP 的文档(尽管我认为 InterOP 在这里不适用,因为客户端和服务器都是托管代码。)

构建组件时需要设置什么吗? (我使用“使 COM 可见”,它似乎确实可以注册它。但是,我注意到,如果我用 Regasm 取消注册它,它不会清除注册表项...

是否有我缺少的 VS 2017 设置或构建中的某些设置?如有任何帮助,我们将不胜感激。

皮特

.NET 无法引用用 .NET 语言编写的 ActiveX 控件或 COM 组件 互操作程序集形式的应用程序。

如果您“添加引用”此类 TLB,或将此类 ActiveX 控件拖放到您的 .NET 应用程序中,您将收到错误消息“ActiveX 类型库 'XXXXX.tlb' 是从 . NET 程序集,无法添加为引用。”支持:无法在 COM 客户端中添加对 COM 的引用?

解决这个问题的正确方法是添加reference.As follows:Right-点击Reference->Add Reference->Browse.

经过大量阅读和实验,我终于解决了这个问题。

总结: 为了能够像使用非托管 COM 组件一样使用托管 COM 组件(一个副本,由所有用户注册和共享),您不应该尝试将 .DLL 添加为项目的引用。相反,您后期绑定组件并使用反射来实现其接口、方法和属性。

这意味着执行以下操作:

  1. 在 运行 时间动态获取组件实例。

  2. 在该实例上使用反射以正常方式访问属性和方法。

详细信息和代码示例(希望让其他人不必做我做的背景...):

第一件事:不要将对 .DLL 的引用添加到您的项目中。

我设置了一些全局变量如下:

现在我需要考虑我想要的操作。我想要一个通用的解决方案,这样我就可以在任何 COM 参考上使用它,我在这里发布的内容很接近,但是像 具体的错误信息还没有被变量替换。

COM对象支持获取和设置属性以及调用方法。我还需要能够轻松实例化它。

我在这里写的方法 return retVal 中的动态值。

它们已经过测试并且运行良好,所以我可以像使用非托管组件一样继续使用托管 COM 组件,只需将此处的代码示例添加到处理它们的任何项目,然后调用这些方法处理给定的托管 COM 组件。我并不声称自己是 C# 方面的专家,而且我相信更有经验的人会找到比我更好的编码方法,但它确实有效,而且这总是一件好事......:-)

我有点担心使用反射可能会减慢一切,但实际上它并不比延迟绑定任何 COM 对象“慢”。

方法如下: (抱歉代码错位;我是新手...)

实例化 COM 对象的方法。该示例使用名为“RAVDesktop.dll”

的东西

现在 COM 对象中属性和方法的“操作”方法...

下面是实例化组件的示例,然后在其中设置一个名为“WebServiceURL”的属性,如果设置成功,则检索它以供检查:

感谢所有贡献者。 Stack Overflow 棒极了!

皮特