Search code examples
.netdllcomvb6com-interop

VB.NET class gets assembly name prepended to name in COM?


I am having a .NET COM assembly A consists of 3 classes say B, C and D. I use to refer this COM dll from my VB6 as A.B, A.C and A.D.

Recently when I tried to recompile my VB6 project, still I am able to reference A.B and A.C.

But class D is getting exposed as A.A_D in the VB6 Object browser. My question is why Class Name and Underscore is getting appended to class D.

I am using .NET framework 4.0 for DLL. Find below Pseudo Code for your reference. ProgID is not used. Instead direct reference to the object is used in VB6.

Class A : Configured as Class Library

Class B:

<ComClass(B.ClassId, B.InterfaceId, B.EventsId), ComVisible(True)> Public Class B

#Region "COM GUIDs"
    'All the real GUIDs/Interface/Events are replaced with zeros for code security purpose
    Public Const ClassId As String = "0000000-0000-0000-0000-000000000000"
    Public Const InterfaceId As String = "00000000-0000-0000-0000-000000000000"
    Public Const EventsId As String = "00000000-0000-0000-0000-000000000000"
#End Region

Class C:

<ComClass(C.ClassId, C.InterfaceId, C.EventsId), ComVisible(True)> Public Class C

#Region "COM GUIDs"
    'All the real GUIDs/Interface/Events are replaced with zeros for code security purpose
    Public Const ClassId As String = "0000000-0000-0000-0000-000000000000"
    Public Const InterfaceId As String = "00000000-0000-0000-0000-000000000000"
    Public Const EventsId As String = "00000000-0000-0000-0000-000000000000"
#End Region

Class D:

<ComClass(D.ClassId, D.InterfaceId, D.EventsId), ComVisible(True)> Public Class D

#Region "GUIDs"
    'All the real GUIDs are replaced with zeros
    Friend Const ClassId As String = "00000000-0000-0000-0000-000000000000"
    Friend Const InterfaceId As String = "00000000-0000-0000-0000-000000000000"
    Friend Const EventsId As String = "00000000-0000-0000-0000-000000000000"
#End Region

In OLEView Class D alone gets prepended with namespace A. Class B and C remains same. When I backtracked this DLL, namespace is getting prepended only after migrating to Framework 4. This problem seems to be similar to the one mentioned in prepending-namespace-to-typelib-coclass-name But the difference here is I am still using Visual Studio 2010 and I do not find

Embed Interop Types property

OLEView.exe Output

coclass D

[uuid(00000000-0000-0000-0000-000000000000),
version(1.0),
custom({00000000-0000-0000-0000-000000000000}, "A.D")]

coclass A_D {
    interface _Object;
    [default] interface _D;
    [default, source] dispinterface __D;
};

coclass B

[uuid(00000000-0000-0000-0000-000000000000),
version(1.0),
custom({00000000-0000-0000-0000-000000000000}, "A.B")]

coclass B{
   interface _Object;
   [default] interface _B;
   [default, source] dispinterface __B;
};

Solution

  • Without seeing the real class name for D its impossible to be certain. But a likely possibility is that the bare name D would conflict with something else and so the compiler (*) adds the assembly name to distinguish it.

    If you want to confirm this you could load the .TLB file for your assembly in OLEView or some similar tool and inspect the IDL, which probably would show the same A_D name.

    Another test would be to change D to almost anything else and recompile and see if that has any effect.

    As noted in a comment using the [ProgId] attribute may be a way to force it to supply a more desirable name in the type library.

    (* Not truly the compiler but the tools which generate the COM wrapper layer & the type library)