Share via


.NET Core-onderdelen beschikbaar maken voor COM

In dit artikel wordt uitgelegd hoe u een klasse beschikbaar maakt voor COM vanuit .NET Core (of .NET 5+). In deze handleiding ontdekt u hoe u:

  • Een klasse beschikbaar maken voor COM vanuit .NET Core.
  • Genereer een COM-server als onderdeel van het bouwen van uw .NET Core-bibliotheek.
  • Genereer automatisch een servermanifest naast elkaar voor registervrije COM.

Vereisten

De bibliotheek maken

De eerste stap is het maken van de bibliotheek.

  1. Maak een nieuwe map en voer in die map de volgende opdracht uit:

    dotnet new classlib
    
  2. Class1.cs openen.

  3. Voeg using System.Runtime.InteropServices; toe aan het begin van het bestand.

  4. Maak een interface met de naam IServer. Voorbeeld:

    using System;
    using System.Runtime.InteropServices;
    
    [ComVisible(true)]
    [Guid(ContractGuids.ServerInterface)]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IServer
    {
        /// <summary>
        /// Compute the value of the constant Pi.
        /// </summary>
        double ComputePi();
    }
    
  5. Voeg het [Guid("<IID>")] kenmerk toe aan de interface, met de interface-GUID voor de COM-interface die u implementeert. Bijvoorbeeld [Guid("fe103d6e-e71b-414c-80bf-982f18f6c1c7")]. Houd er rekening mee dat deze GUID uniek moet zijn, omdat deze de enige id van deze interface voor COM is. In Visual Studio kunt u een GUID genereren door naar Tools > Create GUID te gaan om het hulpprogramma GUID maken te openen.

  6. Voeg het [InterfaceType] kenmerk toe aan de interface en geef op welke COM-basisinterfaces uw interface moet implementeren.

  7. Maak een klasse met de naam Server die wordt geïmplementeerd IServer.

  8. Voeg het [Guid("<CLSID>")] kenmerk toe aan de klasse, met de GUID van de klasse-id voor de COM-klasse die u implementeert. Bijvoorbeeld [Guid("9f35b6f5-2c05-4e7f-93aa-ee087f6e7ab6")]. Net als bij de interface-GUID moet deze GUID uniek zijn, omdat dit de enige id van deze interface is voor COM.

  9. Voeg het [ComVisible(true)] kenmerk toe aan zowel de interface als de klasse.

Belangrijk

In tegenstelling tot .NET Framework moet u voor .NET Core de CLSID opgeven van elke klasse die u via COM wilt activeren.

De COM-host genereren

  1. Open het .csproj projectbestand en voeg deze toe <EnableComHosting>true</EnableComHosting> aan een <PropertyGroup></PropertyGroup> tag.
  2. Maak het project.

De resulterende uitvoer heeft een ProjectName.dll, ProjectName.deps.jsonProjectName.runtimeconfig.json en ProjectName.comhost.dll bestand.

De COM-host registreren voor COM

Open een opdrachtprompt met verhoogde bevoegdheid en voer deze uit regsvr32 ProjectName.comhost.dll. Hiermee worden al uw weergegeven .NET-objecten geregistreerd bij COM.

RegFree COM inschakelen

  1. Open het .csproj projectbestand en voeg deze toe <EnableRegFreeCom>true</EnableRegFreeCom> aan een <PropertyGroup></PropertyGroup> tag.
  2. Maak het project.

De resulterende uitvoer heeft nu ook een ProjectName.X.manifest bestand. Dit bestand is het side-by-side manifest voor gebruik met Register-Free COM.

Typebibliotheken insluiten in de COM-host

In tegenstelling tot .NET Framework is er geen ondersteuning in .NET Core of .NET 5+ voor het genereren van een COM-typebibliotheek (TLB) van een .NET-assembly. De richtlijnen zijn het handmatig schrijven van een IDL-bestand of een C/C++-header voor de systeemeigen declaraties van de COM-interfaces. Als u besluit een IDL-bestand te schrijven, kunt u het compileren met de MIDL-compiler van de Visual C++ SDK om een TLB te produceren.

In .NET 6 en latere versies ondersteunt de .NET SDK het insluiten van al gecompileerde TLB's in de COM-host als onderdeel van uw projectbuild.

Als u een typebibliotheek wilt insluiten in uw toepassing, voert u de volgende stappen uit:

  1. Open het .csproj projectbestand en voeg het toe <ComHostTypeLibrary Include="path/to/typelib.tlb" Id="<id>" /> aan een <ItemGroup></ItemGroup> tag.
  2. Vervang door <id> een positief geheel getal. De waarde moet uniek zijn tussen de TLB's die u opgeeft om te worden ingesloten in de COM-host.
    • Het Id kenmerk is optioneel als u er slechts een ComHostTypeLibrary toevoegt aan uw project.

Met het volgende codeblok wordt bijvoorbeeld de Server.tlb typebibliotheek aan 1 de COM-host toegevoegd:

<ItemGroup>
    <ComHostTypeLibrary Include="Server.tlb" Id="1" />
</ItemGroup>

Laden in de standaardinstelling AssemblyLoadContext

Tijdens de activering wordt de assembly met het COM-onderdeel in een afzonderlijk AssemblyLoadContext bestand geladen op basis van het assemblypad. Als er één assembly is die meerdere COM-servers biedt, wordt deze AssemblyLoadContext opnieuw gebruikt, zodat alle servers van die assembly zich in dezelfde belastingscontext bevinden. Als er meerdere assembly's zijn die COM-servers bieden, wordt er een nieuwe AssemblyLoadContext gemaakt voor elke assembly en bevindt elke server zich in de laadcontext die overeenkomt met de assembly.

In .NET 8 en latere versies kan de assembly opgeven dat deze in de standaardversie AssemblyLoadContextmoet worden geladen. Als u het laden in de standaardcontext wilt inschakelen, voegt u het volgende RuntimeHostConfigurationOption-item toe aan het project:

<ItemGroup>
  <RuntimeHostConfigurationOption Include="System.Runtime.InteropServices.COM.LoadComponentInDefaultContext" Value="true" />
</ItemGroup>

Voorbeeld

Er is een volledig functioneel COM-servervoorbeeld in de opslagplaats dotnet/samples op GitHub.

Aanvullende opmerkingen

Belangrijk

In .NET Framework kan een ASSEMBLY van elke CPU worden gebruikt door zowel 32-bits als 64-bits clients. Standaard worden in .NET Core, .NET 5 en latere versies alle CPU-assembly's vergezeld van een 64-bits *.comhost.dll. Hierdoor kunnen ze alleen worden gebruikt door 64-bits clients. Dit is de standaardinstelling omdat dat is wat de SDK vertegenwoordigt. Dit gedrag is identiek aan de manier waarop de zelfstandige functie wordt gepubliceerd: standaard wordt de SDK gebruikt. De NETCoreSdkRuntimeIdentifier eigenschap MSBuild bepaalt de bitheid van *.comhost.dll. Het beheerde onderdeel is eigenlijk bitness-agnostisch zoals verwacht, maar de bijbehorende systeemeigen asset wordt standaard ingesteld op de beoogde SDK.

Zelfstandige implementaties van COM-onderdelen worden niet ondersteund. Alleen frameworkafhankelijke implementaties van COM-onderdelen worden ondersteund.

Daarnaast heeft het laden van zowel .NET Framework als .NET Core in hetzelfde proces diagnostische beperkingen. De primaire beperking is de foutopsporing van beheerde onderdelen, omdat het niet mogelijk is om tegelijkertijd fouten op te sporen in .NET Framework en .NET Core. Bovendien delen de twee runtime-exemplaren geen beheerde assembly's. Dit betekent dat het niet mogelijk is om werkelijke .NET-typen te delen in de twee runtimes en in plaats daarvan moeten alle interacties worden beperkt tot de weergegeven COM-interfacecontracten.