使用C#重建更新的VB6 COM类替换

Jam*_*mer 4 c# vb.net vb6 com vb6-migration

我在这里遇到了一个特别棘手的问题,我想在那里提出更多的反馈(我是我工作的公司中唯一的.NET开发人员,因此没有人可以反弹).

我的任务是更换一个老化的VB6编写的ActiveX组件,该组件由包含VB6用量和我正在替换的组件的VB.NET用法的应用程序使用.

我有所有这些组件的完整源代码,所以我可以看到用例.

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

MyVb6.dll
MyApp(使用VB.NET和VB6组件)

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

Interop.MyVb6.dll

用法

在大多数情况下,使用此方法符合预期,使用如下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
Run Code Online (Sandbox Code Playgroud)

但是在一个例子中,我发现他们似乎已经改变了如何使用这个interop 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
Run Code Online (Sandbox Code Playgroud)

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

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

替换

到目前为止我所做的是编写替换dll的框架,因为对象实例是使用已知的字符串值创建的,所以我添加了这个ProgId,例如:

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

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

然后当我部署它时,我将取消注册旧的COM组件并注册我的新组件.这种尝试是否会试图让它认为创建相同的对象实际上有效?

非常令人讨厌的问题

源代码中也有一些例子,他们直接使用VB6 dll,例如:

Dim myObj As MyVb6.MyVb6Obj
Run Code Online (Sandbox Code Playgroud)

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

如果有人做过类似的事情并让它运转起来,那就太棒了.

Han*_*ant 6

没问题,只需使用正确的名称:

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

请注意不同的接口名称.不要自己写.添加对旧VB6组件的引用,这样您就可以完全确定是否准确地实现了IOldVb6Version接口,并且与IID,方法,它们的顺序和参数完全匹配.如果您不知道旧的接口名称,请查看Oleview.exe,File + View Typelib.

  • 它有接口,它们只是隐藏.但如果你使用Oleview或Tlbimp,肯定非常明显.它并不可怕,将实现与接口隔离是一种标准的互操作方法,在.NET中也很常见.请关闭你的问题. (2认同)