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

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

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

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

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

为了便于讨论,可以将这些组件称为:

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

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

互操作.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

但是在一个实例中,我发现他们似乎已经改变了如何使用这个互操作 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
{
    ...
}

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

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

非常讨厌的问题

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

Dim myObj As MyVb6.MyVb6Obj

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

如果有人做过类似的事情并使其正常工作,那将是一件很棒的事情。

最佳答案

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

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

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

关于c# - 使用 C# 重建更新的 VB6 COM 类替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21835921/

相关文章:

com - VB6编译时可以使用.local文件避免注册COM ocx和dll文件吗

c# - 正确识别具有相同基础值的枚举

c# - 如何使用 RestSharp 发送请求

c# - 尝试使用 Autodesk.AutoCAD.DatabaseService 从 DWG 中读取数据 我需要引用什么 DLL?

vb.net - 如何将 "sub property"添加到类属性

c++ - 调用 IConnectionPoint::Advise 导致崩溃

c# - NHibernate QueryOver 其中值在列表属性/字段中?

c# - 将一个集合分组并从每组中取出前 5 个

java - 在 Vb.net 中使用 If-Statement 作为 For-Loop 的测试条件

c# - Windows UIAutomation 有时会挂起其他应用程序