dscom 0.16.2
See the version list below for details.
dotnet tool install --global dscom --version 0.16.2
dotnet new tool-manifest # if you are setting up this repo dotnet tool install --local dscom --version 0.16.2
#tool dotnet:?package=dscom&version=0.16.2
nuke :add-package dscom --version 0.16.2
dSPACE COM tools
This is an unstable prerelease. Anything may change at any time!
dscom generates a type library that describes the types defined in a common language runtime assembly and 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 net5+
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.
https://docs.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com
One main goal is to make dscom
behave like tlbexp.exe
.
Happy IUnknowing and IDispatching 😉
- dSPACE COM tools
Command Line Client
The command-line interface (CLI) tool dscom
is a replacement for tlbexp.exe
and OleView
(View TypeLib).
It supports the following features:
- Convert an assembly to a type library
- Convert a type library to
YAML
file - Register a type library
- Unregister a type library
Installation
The installation is quite simple. You can use dotnet tool
to install the dscom
binary if you want to create a 64Bit TLB.
dotnet tool install --global dscom
Here you can find all available versions:
https://www.nuget.org/packages/dscom/
Alternatively you can download dscom.exe from the relase page.
https://github.com/dspace-group/dscom/releases
32Bit support
dscom
installed by dotnet tool install
can only handle AnyCPU or 64Bit assemblies and can only generate a 64bit TLB.
Depending on whether you want to process 32bit or 64bit assemblies, you need to download different executables from the release page.
- dscom.exe to create a 64Bit TLB from a AnyCPU or a 64Bit assembly
- dscom32.exe to create a 32Bit TLB from a AnyCPU or a 32Bit assembly
Warning!
If your assembly is an AnyCPU assembly, then an yourassemblyname.comhost.dll is created as a 64 bit dll.
Therefore after calling regserv32.exe a 64 bit dll is registred.
To prevent this it is recommended that the assembly is compiled as a 32 bit assembly and not as an AnyCPU assembly.
see: https://github.com/dotnet/runtime/issues/32493
Usage
Use dscom --help
to get further information.
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 library
Library
Usage:
dotnet add package dSPACE.Runtime.InteropServices
dSPACE.Runtime.InteropServices supports the following methods and classes:
- TypeLibConverter
- ConvertAssemblyToTypeLib
- RegistrationServices
- RegisterTypeForComClients
- UnregisterTypeForComClients
TypeLibConverter.ConvertAssemblyToTypeLib
If 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)
https://www.nuget.org/packages/dSPACE.Runtime.InteropServices/
Example:
using dSPACE.Runtime.InteropServices;
// The assembly to convert
var assembly = typeof(Program).Assembly;
// Convert to assembly
var typeLibConverter = new TypeLibConverter();
var callback = new TypeLibConverterCallback();
var result = typeLibConverter.ConvertAssemblyToTypeLib(assembly, "MyTypeLib.tlb", callback);
// 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}");
}
// 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;
}
}
RegistrationServices.RegisterTypeForComClients and RegistrationServices.UnregisterTypeForComClients
The dSPACE.Runtime.InteropServices.RegistrationServices
provides a set of services for registering and unregistering managed assemblies for use from COM.
This method is equivalent to calling CoRegisterClassObject in COM.
You can register a .NET class so that other applications can connect to it (For example as INPROC_SERVER or as a LOCAL_SERVER).
A outproc demo application is available here: examples\outproc
Example:
using dSPACE.Runtime.InteropServices;
var registration = new RegistrationServices();
var cookie = registration.RegisterTypeForComClients(typeof(Server.Common.Greeter),
RegistrationClassContext.LocalServer,
RegistrationConnectionType.MultipleUse);
Console.WriteLine($"Press enter to stop the server");
Console.ReadLine();
registration.UnregisterTypeForComClients(cookie);
Migration notes (mscorelib vs System.Private.CoreLib)
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, _Exception
In 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).
Why can I load a .NET Framework library into a .NET application?
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 Framework project if you plan to migrate to .NET 5+
Limitations
- No imports of the
mscorelib
typelib (all types are VT_UNKNOWN)- _Object not supported
- _EventArgs not supported
- _Delegate not supported
- _Type not supported
- System.Runtime.Serialization.ISerializable not supported
- System.ICloneable not supported
- System.IDisposable not supported
- System.Array not supported
- ...
TypeLibExporterFlags
is not supportedITypeLibExporterNotifySink
is not COM visibleTypeLibConverter
is not COM visibleAutoDual
is not supported- LCID only NEUTRAL is supported
- No GAC support
- IEnumerator is converted to
IEnumVARIANT
(stdole) - Guid is converted to
GUID
(stdole) - Color is converted to
OLE_COLOR
(stdole) - No support for
UnmanagedType.CustomMarshaler
- No support for .NET Framework assemblies with
AssemblyMetadataAttribute
value ".NETFrameworkAssembly"
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
This package has no dependencies.
Version | Downloads | Last updated |
---|---|---|
1.12.0 | 44 | 11/20/2024 |
1.11.1 | 276 | 10/29/2024 |
1.11.0 | 334 | 10/3/2024 |
1.10.1 | 834 | 7/1/2024 |
1.10.0 | 718 | 4/30/2024 |
1.9.0 | 346 | 4/19/2024 |
1.8.0 | 352 | 4/15/2024 |
1.7.4 | 489 | 3/4/2024 |
1.7.3 | 533 | 1/9/2024 |
1.7.2 | 172 | 1/8/2024 |
1.7.1 | 219 | 12/12/2023 |
1.7.0 | 227 | 12/1/2023 |
1.6.0 | 185 | 11/20/2023 |
1.5.0 | 159 | 11/16/2023 |
1.4.0 | 137 | 11/15/2023 |
1.3.0 | 252 | 10/16/2023 |
1.2.0 | 248 | 9/18/2023 |
1.1.3 | 289 | 8/31/2023 |
1.1.2 | 357 | 8/10/2023 |
1.1.1 | 239 | 7/16/2023 |
1.1.0 | 210 | 6/20/2023 |
0.23.5 | 368 | 6/12/2023 |
0.23.4 | 211 | 5/8/2023 |
0.23.3 | 352 | 3/22/2023 |
0.23.1 | 278 | 3/17/2023 |
0.23.0 | 268 | 3/10/2023 |
0.22.1 | 282 | 2/24/2023 |
0.22.0 | 275 | 2/20/2023 |
0.21.0 | 271 | 2/16/2023 |
0.20.0 | 294 | 2/7/2023 |
0.19.1 | 460 | 1/19/2023 |
0.19.0 | 315 | 1/18/2023 |
0.18.3 | 334 | 1/5/2023 |
0.18.2 | 361 | 12/19/2022 |
0.18.1 | 353 | 12/19/2022 |
0.18.0 | 353 | 12/15/2022 |
0.17.0 | 417 | 11/29/2022 |
0.16.3 | 463 | 11/9/2022 |
0.16.2 | 429 | 11/3/2022 |
0.16.1 | 446 | 10/24/2022 |
0.16.0 | 903 | 9/20/2022 |
0.15.1 | 453 | 9/6/2022 |
0.15.0 | 1,139 | 7/29/2022 |
0.14.0 | 443 | 7/28/2022 |
0.13.0 | 449 | 7/18/2022 |
0.12.0 | 449 | 7/18/2022 |
0.10.0 | 2,331 | 5/11/2022 |
0.9.0 | 504 | 4/5/2022 |
0.8.1 | 475 | 3/15/2022 |
0.8.0 | 458 | 3/15/2022 |
0.7.2 | 448 | 3/13/2022 |
0.7.1 | 442 | 3/13/2022 |
0.7.0 | 453 | 3/11/2022 |
0.6.0 | 446 | 3/10/2022 |
0.5.0 | 437 | 3/8/2022 |
0.4.0 | 456 | 3/7/2022 |
0.3.1 | 470 | 3/6/2022 |
0.3.0 | 464 | 3/4/2022 |
0.2.0 | 464 | 3/4/2022 |
0.1.0 | 450 | 3/3/2022 |