在 Visual Studio 中添加 VB6 引用会给出“类型库导入器在类型验证期间遇到错误”
Posted
技术标签:
【中文标题】在 Visual Studio 中添加 VB6 引用会给出“类型库导入器在类型验证期间遇到错误”【英文标题】:Adding a VB6 reference in Visual Studio gives "Type library importer encountered an error during type verification" 【发布时间】:2012-09-15 05:51:43 【问题描述】:我正在将一个用 VB6 编写的大型项目转换为 C#。鉴于正在迁移的项目的规模,它将在 18 个月的过程中分阶段完成。我在将 VB6 ActiveX dll 的引用添加到 .Net 项目时遇到了问题。
如果您完全按照这些步骤操作,您也应该能够重现问题。
我在 .Net 中编写了一个 COM 可见的接口:
<ComVisible(True)>
Public Interface ITestInterface
Property A As String
Function TestMethod() As String
End Interface
通过在项目属性的Compile选项卡中选择“Register for COM interop”,您将获得一个TLB文件。
我创建了一个引用此 TLB 的 VB6 项目和一个实现所公开接口的类。
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 并看到以下内容(除了在 .Net 项目中定义的接口在 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 接口的方法(这就是我们真正需要的)。这解决了症状(错误消失了!),但绝对没有解决我的问题中解决的根本问题,因为此解决方案可能不适用于所有人。 很公平,纯粹出于好奇而询问,感谢您的回复! 您确定这是最好的方法吗?我建议你评估一下 activeX 在 vb6 上的作用,并在 vb.net 上搜索最好的方法。例如,您会发现在 vb.net 上包含该功能。我讨厌移植,大多数时候重写它会更快。 【参考方案1】:Visual Studio IDE 在为 COM 互操作注册 DLL 时肯定会采用不同的路径,而不是在从命令提示符运行命令行工具时。
我怀疑微软是否在任何地方都记录了这一点。但是,我多年的经验证明确实如此。我曾经遇到过 .NET 2.0 框架中的“regsvcs”命令实际上会导致无限循环的情况。如果你谷歌它,你可能会发现其他人遇到过这个问题。通过使用 VS IDE 执行 .NET 服务组件的 COM 注册,我能够更进一步。然而,它不可避免地以错误告终。该错误是无限循环的一步。无论哪种方式,它都向我证明了 VS IDE 在处理 COM 互操作和注册表项时采用了不同的代码路径/业务逻辑。
【讨论】:
确实如此。如果有任何警告,它不会导入 TLB。 Tlbimp.exe 在控制台上显示的警告类型,通常可以忽略,因为它们是良性的。给予或接受。以上是关于在 Visual Studio 中添加 VB6 引用会给出“类型库导入器在类型验证期间遇到错误”的主要内容,如果未能解决你的问题,请参考以下文章
从 VB6 调用 C dll,其中 dll 是使用 Visual Studio 2013 编写的