I have been doing some research on .NET Core COM interop and how to expose them.
Though I am having some issues coming up with a conclusion and understanding some concepts. My boss told me they did some tests and they thought the only way to create C# code that could be called from within VB6 (including events) was to create a .NET Framework project, as it was not available in .NET Core 3.1 (at the moment they had to use this feature).
But seeing the previously mentioned page and doing some more research, I do think it looks like .NET Core supports this interoperability. And I do not understand why wouldn't it be possible for the .NET Core platform to do this.
I am sorry if this question does not belong here, but could someone shed some light on this issue?
.NET Framework, .NET Core 3, and .NET 5/6/+ can expose a COM object to the COM world. This world includes VB6 and everything that can do COM.
a) Create a .NET 5 "NetClassLibrary" Class Library project (using Visual Studio for example)
b) Add a NetComObject.cs
file with the following code for example:
using System;
using System.Runtime.InteropServices;
namespace NetClassLibrary
{
[ComVisible(true)]
[Guid("cfb2ee8b-f2ec-447c-9f0d-ac19c9a6cc26")] // TODO: change this GUID
public class NetComObject
{
public string SayHello() => "Hello World from .NET " + RuntimeInformation.FrameworkDescription;
}
}
c) Modify the .csproj to set the EnableComHosting
property to true
and make sure you compile for x86 as VB6 is a 32-bit program (note if you use Excel's 64-bit VBA, not VB6, you must compile for 64-bit), like this for example:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<EnableComHosting>true</EnableComHosting>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
</Project>
d) Compile, start an admin prompt and run this:
regsvr32 yourPathTo\NetClassLibrary.comhost.dll
e) Create a VB6 project, add this VB6 code:
Private Sub Form_Load()
Dim obj As Object
Set obj = CreateObject("new:{cfb2ee8b-f2ec-447c-9f0d-ac19c9a6cc26}") // TODO: use the same GUID!
MsgBox obj.SayHello()
End Sub
f) Run
Note 1: you can use a ProgId attribute too, like COM object often do, you don't have to stick to Guids only...
Note 2: I've only used IDispatch
("Lazy Loading") interface for this demonstration but you can use IUnknown
-derived interfaces ("Early Loading") and TLBs too. Unfortunately .NET 5 doesn't create the .TLB for you, you'll have to build it by yourself or create it with another tool and import it in .NET and/or in VB6.