Share via


Exposer les composants .NET Core à COM

Cet article vous guide tout au long de l’exposition d’une classe à COM à partir de .NET Core (ou .NET 5+). Ce didacticiel vous explique les procédures suivantes :

  • Exposer une classe à COM à partir de .NET Core.
  • Générer un serveur COM dans le cadre de la génération de votre bibliothèque .NET Core.
  • Générer automatiquement un manifeste de serveur côte à côte pour COM sans registre.

Prérequis

Créer la bibliothèque

La première étape consiste à créer la bibliothèque.

  1. Créez un dossier et, dans ce dossier, exécutez la commande suivante :

    dotnet new classlib
    
  2. Ouvrez Class1.cs.

  3. Ajoutez using System.Runtime.InteropServices; en haut du fichier.

  4. Créez une interface nommée IServer. Par exemple :

    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. Ajoutez l’attribut [Guid("<IID>")] à l’interface, avec le GUID d’interface pour l’interface COM que vous implémentez. Par exemple : [Guid("fe103d6e-e71b-414c-80bf-982f18f6c1c7")]. Notez que ce GUID doit être unique, car il s’agit du seul identificateur de cette interface pour COM. Dans Visual Studio, vous pouvez générer un GUID en accédant à Outils > Créer un GUID pour ouvrir l’outil Créer un GUID.

  6. Ajoutez l’attribut [InterfaceType] à l’interface et spécifiez les interfaces COM de base que votre interface doit implémenter.

  7. Créez une classe nommée Server qui implémente IServer.

  8. Ajoutez l’attribut [Guid("<CLSID>")] à la classe, avec le GUID de l’identificateur de classe pour la classe COM que vous implémentez. Par exemple : [Guid("9f35b6f5-2c05-4e7f-93aa-ee087f6e7ab6")]. Comme avec le GUID d’interface, ce GUID doit être unique, car il est le seul identificateur de cette interface pour COM.

  9. Ajoutez l’attribut [ComVisible(true)] à la fois à l’interface et à la classe.

Important

Contrairement au .NET Framework, .NET Core vous oblige à spécifier le CLSID des classes que vous voulez rendre activables via COM.

Générer l’hôte COM

  1. Ouvrez le fichier projet .csproj et ajoutez <EnableComHosting>true</EnableComHosting> à l’intérieur d’une balise <PropertyGroup></PropertyGroup>.
  2. Créez le projet.

La sortie résultante a un fichier ProjectName.dll, ProjectName.deps.json, ProjectName.runtimeconfig.json et ProjectName.comhost.dll.

Inscrire l’hôte COM pour COM

Ouvrez une invite de commandes avec élévation de privilèges et exécutez regsvr32 ProjectName.comhost.dll. Ceci inscrit tous vos objets .NET exposés auprès de COM.

Activation de COM sans registre

  1. Ouvrez le fichier projet .csproj et ajoutez <EnableRegFreeCom>true</EnableRegFreeCom> à l’intérieur d’une balise <PropertyGroup></PropertyGroup>.
  2. Créez le projet.

La sortie résultante a un fichier ProjectName.X.manifest. Ce fichier est le manifeste côte à côte à utiliser avec COM sans registre.

Incorporation de bibliothèques de types dans l’hôte COM

Contrairement au .NET Framework, .NET Core ou .NET 5+ ne prend pas en charge la génération d’une bibliothèque de types COM (TLB) à partir d’un assembly .NET. L’aide consiste à écrire manuellement un fichier IDL ou un en-tête C/C++ pour les déclarations natives des interfaces COM. Si vous décidez d’écrire un fichier IDL, vous pouvez le compiler avec le compilateur MIDL du SDK Visual C++ pour produire une TLB.

Dans .NET 6 et versions ultérieures, le Kit de développement logiciel (SDK) .NET prend en charge l’incorporation de bases de données déjà compilées dans l’hôte COM dans le cadre de la génération de votre projet.

Pour incorporer une bibliothèque de types dans votre application, procédez comme suit :

  1. Ouvrez le fichier projet .csproj et ajoutez <ComHostTypeLibrary Include="path/to/typelib.tlb" Id="<id>" /> à l’intérieur d’une balise <ItemGroup></ItemGroup>.
  2. Remplacez <id> par une valeur entière positive. La valeur doit être unique parmi les TLB que vous spécifiez pour être incorporée dans l’hôte COM.
    • L’attribut Id est facultatif si vous n’ajoutez qu’un ComHostTypeLibrary à votre projet.

Par exemple, le bloc de code suivant ajoute la bibliothèque de type Server.tlb à l’index 1 à l’hôte COM :

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

Chargement dans le AssemblyLoadContext par défaut

Pendant l’activation, l’assembly contenant le composant COM est chargé dans un autre AssemblyLoadContext en fonction du chemin d’accès de l’assembly. S’il existe un assembly fournissant plusieurs serveurs COM, le AssemblyLoadContext est réutilisé de sorte que tous les serveurs de cet assembly résident dans le même contexte de charge. S’il existe plusieurs assemblys fournissant des serveurs COM, un nouveau AssemblyLoadContext est créé pour chaque assembly et chaque serveur réside dans le contexte de charge qui correspond à son assembly.

Dans .NET 8 et les versions ultérieures, l’assembly peut spécifier qu’il doit être chargé dans le AssemblyLoadContext par défaut. Pour activer le chargement dans le contexte par défaut, ajoutez l’élément RuntimeHostConfigurationOption suivant au projet :

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

Exemple

Un exemple de serveur COM entièrement fonctionnel se trouve dans le dépôt dotnet/samples sur GitHub.

Remarques supplémentaires

Important

Dans .NET Framework, un assembly « N’importe quel processeur » peut être consommé par les clients 32 bits et 64 bits. Par défaut, dans .NET Core, .NET 5 et versions ultérieures, les assemblys « N’importe quel processeur » sont accompagnés d’un *.comhost.dll 64 bits. Pour cette raison, ils ne peuvent être consommés que par les clients 64 bits. Il s’agit de la valeur par défaut, car c’est ce que représente le SDK. Ce comportement est identique à la façon dont la fonctionnalité « autonome » est publiée : par défaut, elle utilise ce que fournit le Kit de développement logiciel (SDK). La propriété MSBuild NETCoreSdkRuntimeIdentifier détermine le nombre de bits de *.comhost.dll. La partie gérée est en fait indépendante des bits comme prévu, mais la ressource native associée est définie par défaut sur le Kit de développement logiciel (SDK) ciblé.

Les déploiements autonomes de composants COM ne sont pas pris en charge. Seuls les déploiements dépendants de l’infrastructure de composants COM sont pris en charge.

En outre, le chargement du .NET Framework et du .NET Core dans le même processus a des limitations de diagnostic. La principale limitation est le débogage des composants managés, car il n’est pas possible de déboguer .NET Framework et .NET Core en même temps. De plus, les deux instances de runtime ne partagent pas d’assemblys managés. Cela signifie qu’il n’est pas possible de partager des types .NET réels entre les deux runtimes et que toutes les interactions doivent être limitées aux contrats d’interface COM exposés.