从.NET程序集创建对象时VB6中的后期绑定运行时错误

时间:2012-02-03 07:57:49

标签: com vb6 activex com-interop

我有一个vb6项目,它引用了一个vb.net com库。

当我使用早期绑定时项目运行良好,例如:

Dim b as object
Set b = new myComLib.testObject

当我使用后期绑定时,例如:

Dim b as object
Set b = CreateObject("myComLib.testObject")

我收到以下错误:

  

运行时错误'':ActiveX组件无法创建对象

有什么想法吗?

感谢

2 个答案:

答案 0 :(得分:5)

在这种情况下,.NET COM Interop类的注册表项是: -

HKEY_CLASSES_ROOT\myComLib.testObject 

包含CLSID值和CLSID条目本身

HKEY_CLASSES_ROOT\CLSID\<<myComLib.testObject\CLSID value>>

它们也在

中复制
HKEY_LOCAL_MACHINE\SOFTWARE\Classes

CreateObject使用HKEY_CLASSES_ROOT条目来检索传入的类名的详细信息,如果它们丢失,您将收到

  

运行时错误'429':ActiveX组件无法创建对象

在VB6 IDE中,添加对dll的引用(在.NET程序集的情况下,通过它的tlb文件)绕过此注册表搜索,从而允许早期绑定在没有COM注册表项的情况下工作。

必须正确注册类才能使CreateObject正常工作。这应该作为Visual Studio构建过程的一部分发生,否则需要使用Regasm手动注册。

您可以通过执行以下操作来测试此行为: -

1)创建一个新的VB.NET项目myComLib在项目中注册COM Interop编译属性并添加一个类testObject

Public Class testObject

    Public Property TestProperty As String

    Public Function TestFunction() As String
        Return "return"
    End Function

End Class

2)构建myComLib

3)创建一个新的VB6项目,向Form1添加两个命令按钮和以下代码

Private Sub Command1_Click()
   Dim b As Object
   Set b = New myComLib.testObject
   b.TestProperty = "Hello"
   MsgBox b.TestProperty, vbOKOnly, b.TestFunction()
End Sub

Private Sub Command2_Click()
   Dim b As Object
   Set b = CreateObject("myComLib.testObject")
   b.TestProperty = "Hello"
   MsgBox b.TestProperty, vbOKOnly, b.TestFunction()
End Sub

4)运行VB6项目(没有完全编译,因为它将失败)

Command2将弹出一个消息框,Command1将失败并显示

  

编译错误:未定义用户定义的类型。

5)停止项目并通过它的tlb文件添加对myComLib的引用

6)运行VB6项目,两个按钮现在都可以正常工作

7)进入注册表并删除HKEY_CLASSES_ROOT \ myComLib.testObject条目(这可以通过重建.NET组件重新创建,您需要关闭VB6才能进行重建)

Command2现在将失败

  

运行时错误'429':ActiveX组件无法创建对象

直到重新添加注册表项。

答案 1 :(得分:0)

如果您是ClassInterfaceType.None设置,则必须在班级中添加ProgId属性以允许后期绑定。

例如:

[Guid("B1E17DF6-9578-4D24-B578-9C70979E2F05")]
public interface _Class1
{
    [DispId(1)]
    string TestingAMethod();
}

[Guid("197A7A57-E59F-41C9-82C8-A2F051ABA53C")]
[ProgId("Rubberduck.SourceControl.Class1")]
[ClassInterface(ClassInterfaceType.None)]
public class Class1 : _Class1
{
    public string TestingAMethod()
    {
        return "Hello World";
    }

}