dSPACE COM tools
$ dotnet add package dscomdscom is a replacement for tlbexp.exe and TypeLibConverter.ConvertAssemblyToTypeLib.
The tool consists of a library and a command line tool. The library can be used in net6.0 or in net48 projects.
Fortunately, .NET still supports COM, but there is no support for generating TLBs.
From the Microsoft documentation:
Unlike in .NET Framework, there is no support in .NET Core or .NET 5+ for generating a COM Type Library (TLB) from a .NET assembly.
One main goal is to make dscom behave like tlbexp.exe.
Happy IUnknowing and IDispatching ;-)
The command-line interface (CLI) tool dscom is a replacement for tlbexp.exe and OleView (View TypeLib).
It supports the following features:
YAML fileThe installation is quite simple. You can use dotnet tool to install the dscom binary.
c:\> dotnet tool install --global dscomHere you can find all available versions:
https://www.nuget.org/packages/dscom/
c:\> dscom --help
Description:
dSPACE COM tools
Usage:
dscom [command] [options]
Options:
--version Show version information
-?, -h, --help Show help and usage information
Commands:
tlbexport <Assembly> Export the assembly to the specified type library
tlbdump <TypeLibrary> Dump a type library
tlbregister <TypeLibrary> Register a type library
tlbunregister <TypeLibrary> Unregister a type libraryIf you miss the TypeLibConverter class and the ConvertAssemblyToTypeLib method in .NET, then the dSPACE.Runtime.InteropServices might help you.
This method should behave compatible to the .NET Framework method.
public object? ConvertAssemblyToTypeLib(Assembly assembly, string tlbFilePath, ITypeLibExporterNotifySink? notifySink)Example:
using dSPACE.Runtime.InteropServices;
// The assembly to convert
var assemblyToConvert = typeof(Program).Assembly;
// Convert to assembly
var typeLibConverter = new TypeLibConverter();
var result = typeLibConverter.ConvertAssemblyToTypeLib(assemblyToConvert, "MyTypeLib.tlb", new TypeLibConverterCallback());
// Get the name of the type library
var typeLib2 = result as System.Runtime.InteropServices.ComTypes.ITypeLib2;
if (typeLib2 != null)
{
typeLib2.GetDocumentation(-1, out string name, out _, out _, out _);
Console.WriteLine($"TypeLib name: {name}");
}
// Save the type library to a file
var createTypeLibInstance = result as dSPACE.Runtime.InteropServices.ComTypes.ICreateTypeLib2;
if (createTypeLibInstance != null)
{
var hresult = createTypeLibInstance.SaveAllChanges();
hresult.ThrowIfFailed();
}
// The callback to load additional type libraries, if necessary
public class TypeLibConverterCallback : ITypeLibExporterNotifySink
{
public void ReportEvent(ExporterEventKind eventKind, int eventCode, string eventMsg)
{
Console.WriteLine($"{eventCode}: {eventMsg}");
}
public object ResolveRef(System.Reflection.Assembly assembly)
{
// Returns additional type libraries
return null;
}
}Both assemblies are ComVisible=false but lot of .NET Framework types are ComVisible=true.
But this is not the case for .NET (.NET Core and .NET >= 5).
Unlike mscorelib (the good old .NET Framework), no tlb is shipped for .NET.
As example the System.Exception class:
In case of mscorelib the System.Exception class is ComVisible=true:
[Serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_Exception))]
[ComVisible(true)]
public class Exception : ISerializable, _ExceptionIn case of System.Private.CoreLib (.NET Core and .NET >=5), the Exception class is ComVisible=false
[Serializable]
[TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public class Exception : ISerializable
{The _Exception class interface (default interface in this case) is not available in .NET (.NET Core and .NET >=5).
The magic is in TypeForwardedFromAttribute.
If you try to load an .NET Framework assembly inside a .NET (.NET Core and .NET >=5) application, the runtime will forward the original type to
a type defined in the System.Private.CoreLib assembly.
classextern forwarder System.Exception
{
.assemblyextern System.Private.CoreLib
}Therefore you should make sure that you do not use any types from the mscorelib typelib in your .NET project if you are using .NET Framework assemblies!
mscorelib typelib (are types are VT_UNKNOWN)
TypeLibExporterFlags is not supportedITypeLibExporterNotifySink is not COM visibleTypeLibConverter is not COM visibleAutoDual is not supported
IEnumVARIANT (stdole)GUID (stdole)OLE_COLOR(stdole)UnmanagedType.CustomMarshalerAssemblyMetadataAttribute value ".NETFrameworkAssembly"