【问题标题】:VB6 COM Class Replacement With C# Rebuilt UpdateVB6 COM 类替换与 C# 重建更新
【发布时间】:2014-03-17 03:40:05
【问题描述】:

我在这里遇到了一个特别棘手的情况,我想把它扔在那里以获得更多反馈(我是我工作的公司中唯一的 .NET 开发人员,所以没有人会反弹)。

我的任务是替换一个老化的 VB6 创作的 ActiveX 组件,该组件由包含我要替换的组件的 VB6 使用和 VB.NET 使用的应用程序使用。

我拥有所有这些组件的完整源代码,因此我可以查看用例。

为了便于讨论,可以调用组件:

MyVb6.dll
MyApp(带有 VB.NET 和 VB6 组件)

MyApp 的构建过程中,他们使用 TlbImp 工具生成互操作库:

Interop.MyVb6.dll

用法

在大多数情况下,this 的用法与预期一致,使用 CreateObject() 方法,例如:

Private Property MyProp() As Object
    Get
        Try
            If m_myProp Is Nothing Then
                m_myProp = CreateObject("MyVb6.MyVb6Obj")
                m_myProp.Initialize()
            End If
        Catch : End Try
        Return m_myProp
    End Get

然而,在一个实例中,我发现他们似乎改变了如何使用这个互操作 dll 的策略,并且他们有一个对它的静态引用和一个类型化的属性,例如:

Private Property MyProp() As MyVb6.MyVb6ObjClass 'Whilst this is strongly typed, it is from the interop dll ...
    Get
        If m_myProp Is Nothing Then
            m_myProp = CreateObject("MyVb6.MyVb6Obj")
            m_myProp .Initialize()
        End If
        Return m_myProp 
    End Get

重建和重新部署整个应用程序的费用完全不可能,所以我别无选择,只能替换 MyVb6.dll

我希望在这里找到的是这是否是一个实用的解决方案......

替换

到目前为止,我所做的是编写替换 dll 的骨架,并且由于对象实例是使用已知字符串值创建的,因此我添加了 ProgId,例如:

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[Guid("xxx")]
[ProgId("MyVb6.MyVb6Obj")]
public class MyNewCSharpVersion : IMyNewCSharpVersion
{
    ...
}

显然,对于每个对象,我都维护了一个相同的接口,因此调用应用程序将找到所有预期的方法来调用等。

然后,当我部署它时,我将取消注册旧的 COM 组件并注册我的新组件。这种试图欺骗它认为它正在创建同一个对象的尝试是否真的有效?

非常讨厌的问题

源码中也有直接使用VB6 dll的例子,如:

Dim myObj As MyVb6.MyVb6Obj

不幸的是,如果这个特定组件仍在使用中,没有人可以回答这个问题,这本身就有点令人担忧。

如果有人做过类似的事情并让它发挥作用,那就太好了。

【问题讨论】:

  • AFAIK 不可能这样做:.net dll -> com -> .net dll。但是,您可以这样做:.net dll -> com -> vb6 dll -> com -> .net dll
  • 你应该考虑买一本 Adam Nathan 的书 .NET and COM: The Complete Interoperability Guide。它有一章专门介绍如何在 .NET 组件中重新实现 COM 接口,以及许多其他有用的信息。

标签: c# vb.net com vb6 vb6-migration


【解决方案1】:

没问题,使用正确的名称即可:

namespace MyVb6 {
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("xxx")]
    public class MyVb6Obj : _IOldVb6Version
    {
        ...
    }
}

注意不同的接口名称。不要自己写。添加对旧 VB6 组件的引用,这样您就可以完全确定您在 IID、方法、它们的顺序和参数上使用 exact 匹配准确地实现了 IOldVb6Version 接口。如果您不知道旧接口名称,请查看 Oleview.exe,文件 + 视图类型库。

【讨论】:

  • 啊,好的。旧的 VB6 组件没有定义任何接口,但我认为如果我使用在 TblImp 生成的 Interop dll 中生成的接口,这应该可以工作......看起来很可怕,但如果这就是它所需要的......
  • 它确实有接口,只是被隐藏了。但如果您使用 Oleview 或 Tlbimp,肯定会非常明显。这并不可怕,将实现与接口隔离是一种标准的互操作方法,在 .NET 中也很常见。请关闭您的问题。
  • 我在一般编码中使用了很多接口,只是感觉有点乱,我想把旧东西放在一边。感谢汉斯提供的信息,非常感谢。
猜你喜欢
  • 1970-01-01
  • 2011-07-13
  • 2011-07-02
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-12
相关资源
最近更新 更多