【发布时间】: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