在Visual Studio中添加VB6引用时出现“类型库导入程序在类型验证期间遇到错误”

9

我正在将一个相当庞大的VB6项目转换为C#。考虑到项目的规模,该过程将在18个月内分阶段进行。我遇到了一个问题,无法将VB6 ActiveX dll的引用添加到.Net项目中。

如果你按照以下步骤操作,也应该能够重现这个问题。

我已经在.Net中编写了一个COM可见的接口:

<ComVisible(True)>
Public Interface ITestInterface
    Property A As String
    Function TestMethod() As String
End Interface

通过在项目属性的“编译”选项卡中选择“注册COM互操作性”,您将获得一个TLB文件。
我创建了一个VB6项目,引用了这个TLB以及实现接口的类。
Implements ITestInterface

Private mA As String

Public Property Get ITestInterface_A() As String
    ITestInterface_A = mA
End Property

Public Property Let ITestInterface_A(ByVal value As String)
    mA = value
End Property

Public Function ITestInterface_TestMethod() As String
    ITestInterface_TestMethod = "From VB6"
End Function

如果我在VB6项目属性的组件选项卡中设置使用“远程服务器文件”,则在编译时会自动创建一个TLB。我可以在OleView中查看该TLB,并查看以下内容(除了VB6中定义的接口的具体实现细节之外):

// typelib filename: TestVB6Interface.dll

[
  uuid(**EF005573-BFC7-436D-A382-F906CA09F94A**),
  version(3.0)
]

// ... some other stuff

// TLib :     // TLib :  : {79EC733A-0267-4506-8D38-C4D4655E0755}
importlib("SimpleDotNetLibrary.tlb");

现在我创建了一个全新的 .Net 项目。如果我添加对 VB6 dll 的引用,会出现以下错误:

无法解析 COM 引用“ef005573-bfc7-436d-a382-f906ca09f94a”版本 3.0。类型库导入程序在类型验证期间遇到错误。请尝试不导入类成员进行导入。

但是,如果我启动 Visual Studio 命令提示符并运行以下命令:

tlbimp TestVB6Interface.tlb /out:TestVB6Interface.MyInterop.dll

那么我可以将该dll作为引用添加到我的.Net解决方案中,它可以完美地工作。

我的问题是,tlbimp在命令行上执行的操作与直接添加引用时有什么不同?当Visual Studio中的消息显示“尝试导入没有类成员”时,我该如何在Visual Studio中实现这一点?我知道如何在tlbimp中做到这一点。

对于这篇文字墙,我感到抱歉,但我希望尽可能详细地描述情况,并保留我认为相关的信息。


我们做到了(有点儿)。实现.Net接口的VB6类需要设置为“Attribute VB_Exposed = False”。这意味着它不在TLB中,也不会暴露在VB6 DLL之外,但仍然可以传递通过COM公开的期望.Net接口的方法(这正是我们真正需要的)。这解决了症状(错误消失了!),但绝对没有解决我问题中提到的根本问题,因为这个解决方案可能并不适用于所有人。 - Jason
好的,纯粹出于好奇心而问,谢谢回复! - JMK
你确定这是最好的方法吗?我建议你评估一下在VB6上该ActiveX的功能,并寻找在VB.NET上实现它的最佳方式。例如,你可能会发现在VB.NET中已经包含了该函数。我讨厌移植,大多数情况下重写会更快。 - Gaucho
1个回答

2

在注册DLL进行COM互操作时,Visual Studio IDE与从命令提示符运行命令行工具的方式完全不同。

我怀疑微软没有在任何地方记录这一点。然而,我的多年经验证明了这一点。曾经遇到过一种情况,.NET 2.0 Framework的 “regsvcs” 命令实际上会导致无限循环。如果你在谷歌上搜索这个问题,你可能会发现其他人也曾经遇到过。使用VS IDE执行.NET Serviced 组件的COM注册,我能够向前迈出一步。但是它最终以错误告终。无论哪种方式,都向我证明了当处理COM互操作和注册表条目时,VS IDE采用了不同的代码路径/业务逻辑。


它确实如此。如果存在任何警告,它将不会导入TLB。 Tlbimp.exe在控制台上显示的警告类型通常可以被忽略,因为它们是无害的。多多少少。 - Hans Passant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接