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

通过在项目属性的 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 中做到这一点。

我为文字墙道歉,但我想尽可能地描述情况,保留我认为相关的信息。

4

1 回答 1

2

在为 COM 互操作注册 DLL 时,Visual Studio IDE 肯定会采用不同的路径,而不是在从命令提示符运行命令行工具时。

我怀疑微软是否已经在任何地方记录了这一点。但是,我多年的经验证明确实如此。我曾经遇到过 .NET 2.0 框架中的“regsvcs”命令实际上会导致无限循环的情况。如果你谷歌它,你可能会发现其他人遇到过这个问题。通过使用 VS IDE 执行 .NET 服务组件的 COM 注册,我能够更进一步。然而,它不可避免地以错误告终。该错误是无限循环的一步。无论哪种方式,它都向我证明了 VS IDE 在处理 COM 互操作和注册表项时采用了不同的代码路径/业务逻辑。

于 2013-04-07T04:41:57.103 回答