Late binding run-time error in VB6 when creating an object from a .NET assembly

后端 未结 2 1851
一整个雨季
一整个雨季 2021-01-18 10:10

i have a vb6 project that has a reference to a vb.net com library.

the project runs well when i use early binding such as:

Dim b as object
Set b = ne         


        
相关标签:
2条回答
  • 2021-01-18 10:50

    If you're the ClassInterfaceType.None setting, You have to add a ProgId attribute to your class to allow late binding.

    For example:

    [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";
        }
    
    }
    
    0 讨论(0)
  • 2021-01-18 11:12

    The registry entries for the .NET COM Interop class in this case are:-

    HKEY_CLASSES_ROOT\myComLib.testObject 
    

    containing a CLSID value and the CLSID entry itself

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

    They are also replicated in

    HKEY_LOCAL_MACHINE\SOFTWARE\Classes
    

    CreateObject uses the HKEY_CLASSES_ROOT entries to retrieve the details of the class name passed in so if they're missing you will receive

    Run-time error '429': ActiveX component can't create object

    Within the VB6 IDE, adding a reference to the dll (in the case of a .NET assembly, via it's tlb file) bypasses this registry search thereby allowing the early binding to work without the COM registry entries.

    The class has to be correctly registered for CreateObject to work. This should occur as part of the Visual Studio build process, otherwise it needs to be registered manually using Regasm.

    You can test this behaviour by doing the following:-

    1) Create a new VB.NET project myComLib registering for COM Interop in the project Compile properties and add a class testObject

    Public Class testObject
    
        Public Property TestProperty As String
    
        Public Function TestFunction() As String
            Return "return"
        End Function
    
    End Class
    

    2) Build myComLib

    3) Create a new VB6 project, add two command buttons to Form1 and the following code

    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) Run the VB6 project (without full compile as that will fail)

    Command2 will popup a message box, Command1 will fail with

    Compile Error: User-defined type not defined.

    5) Stop the project and add a reference to myComLib via it's tlb file

    6) Run the VB6 project and both buttons should now work

    7) Go into the registry and delete the HKEY_CLASSES_ROOT\myComLib.testObject entry (this can be re-created by Rebuilding the .NET component, you'll need to close VB6 to carry out the rebuild)

    Command2 will now fail with

    Run-time error '429': ActiveX component can't create object

    until the registry entry is re-added.

    0 讨论(0)
提交回复
热议问题