COM对象注册 - 允许多个?

时间:2013-09-10 21:27:30

标签: c# windows com vb6

我有两个具有不同GUID值的COM对象,但名称相同。一个是另一个的较新版本。使用Name.exe /regserver注册时会发生什么?我查看了注册表,它们都显示相同的ProgID,但它们各自的GUID值不同。他们指向硬盘上的不同位置。这是一个问题吗?

我正在努力让项目的旧版本与项目的新版本一起工作(但不能同时运行),我认为这两件事情都在战斗。

COM对象是在VB6中创建的。使用它们的代码是C#。它们作为引用添加到各自的C#项目中。当一个人注册时,我无法编译另一个(也没有成功运行)。

在调查此问题时,还有哪些其他信息有用?

3 个答案:

答案 0 :(得分:1)

将我的评论转换为答案:

您创建了一个与旧版本不向后兼容的组件的新版本。

您确实应该更改ProgID以表明这实际上是一个新组件。客户端应用必须明确定位新组件或旧组件。人们通常只是将版本号(例如2)附加到ProgId

答案 1 :(得分:1)

您违反了严格的COM规则。您的替换件必须与您替换的组件完全匹配。或者您必须生成以下新版本:

  • 为coclass使用不同的[Guid],你做得恰到好处。
  • 使用不同的 ProgId,你没有这样做。 Boilerplate将在ProgId本身中包含版本号。所以Foo.Bar变成了Foo.Bar.2
  • 对类实现的接口使用不同的 [Guids]。这很容易被忽视,因为它们在VB6组件中隐藏得很好。然而,每当从另一间公寓使用该课程时,至关重要。 COM需要找到组件的类型库,以便它知道如何编组接口方法调用。请务必在C#代码中明确声明您的接口。

仔细检查所有这些的最佳方法是运行OleView.exe,File + View Typelib命令。将类型库内容反编译回IDL,您将看到guids和接口。如果要创建旧组件的精确替代品,那么一切都必须完全匹配。完全相同的guid,完全相同的接口,具有完全相同的方法顺序和完全相同的参数。

答案 2 :(得分:0)

我还没有从.NET(只是dll)访问VB6 ActiveX exes,所以这是一个黑暗的镜头(并且很弱,只是一个评论,除了它太长)。

也许你可以为两个VB6组件创建/导出.tlb来编译你的C#。你不应该需要exes来编译。

接下来手动添加注册表项,就好像它们有单独的程序ID(比如MyComponent.ServerClass.1MyComponent.ServerClass.2),然后在C#中按名称加载它们。