Search code examples
vb.netcomvb6

VB6 program doesn't see properties for VB.Net COM DLL


My client has a VB6 program installed on a large number of computers around the world. It now needs to access an external system via a REST API. I created a Class Library in VB.Net targeting .NET Framework 4. (That's the most recent version installed everywhere.) The DLL exposes about a dozen public functions and subroutines, and ~40 properties. I tested the DLL using this PowerShell code:

[System.Reflection.Assembly]::LoadFile( "$directorypath\Debug\MyExample.dll")
$quotaInstance = new-object MyExample.ComClass1

All of the methods and properties are accessible from the PS script. When I load the DLL into the VB6 IDE, however, the object browser only shows the methods, not the properties. If I can't figure this out, I will have to re-code them as a bunch of functions and subroutines. I hate that idea.

The question How to make properties visible to COM in a .NET DLL (Methods DO work) looks similar, but I'm not (explicitly, see below) using an interface, and I'm not certain that the question was even ever answered.

Does anyone know what's going on, and (more importantly) how to fix it? Thanks!

Update: People have asked to see my code, so here is a striped down sample. I'm guessing from the InterfaceId that Visual Studio Community 2017 is creating an interface of some sort for me.

<ComClass(Example.ClassId, Example.InterfaceId, Example.EventsId)>
Public Class Example

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "099bfc91-1f82-4a26-b1e0-d9645bb1714d"
    Public Const InterfaceId As String = "13e9763d-455c-4d89-8323-cc4e7ae7648e"
    Public Const EventsId As String = "773feeba-e635-4411-b175-30b345afa841"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub

    ' *** Auto-implemented properties
    ' When you declare an auto-implemented property, Visual Basic automatically
    ' creates a hidden Private field called the backing field to contain the
    ' Property value. The backing field name is the auto-implemented Property
    ' name preceded by an underscore (_).

    Public Property Foo As String
    Public Property Bar As Integer

    Public Function InitiateSession(ExampleServer As String) As Boolean
        ' Creates a new API_session.
        ' Returns True if the connection was successful, otherwise False
        ' ...
    End Function

    Public Sub CloseSession()
        ' Releases the current API_session.
        ' ...
    End Sub
End Class

Solution

  • For some unknown reason, the automatic interface generation provided by the VB Compiler for classes marked with the ComClassAttribute ignores auto-implemented properties. You need to explicitly code the long-form for properties.

    So instead of the auto-implemented form of:

    Public Property Foo As String
    

    You need:

    Private _Foo As String
    Public Property Foo As String
        Get
            Return _Foo
        End Get
        Set(value As String)
            _Foo = value
        End Set
    End Property
    

    for Foo to be included in the COM interface.