Uwidacznianie składników .NET Core dla modelu COM

W tym artykule przedstawiono sposób uwidaczniania klasy modelu COM z platformy .NET Core (lub .NET 5+). Ten samouczek przedstawia sposób wykonania następujących czynności:

  • Uwidaczniaj klasę com z platformy .NET Core.
  • Wygeneruj serwer COM w ramach tworzenia biblioteki .NET Core.
  • Automatycznie wygeneruj manifest serwera równoległego dla modelu COM bez rejestru.

Wymagania wstępne

Tworzenie biblioteki

Pierwszym krokiem jest utworzenie biblioteki.

  1. Utwórz nowy folder, a w tym folderze uruchom następujące polecenie:

    dotnet new classlib
    
  2. Otwórz Class1.cs.

  3. Dodaj using System.Runtime.InteropServices; do góry pliku.

  4. Utwórz interfejs o nazwie IServer. Na przykład:

    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. [Guid("<IID>")] Dodaj atrybut do interfejsu z identyfikatorem GUID interfejsu dla implementowanego interfejsu COM. Na przykład [Guid("fe103d6e-e71b-414c-80bf-982f18f6c1c7")]. Należy pamiętać, że ten identyfikator GUID musi być unikatowy, ponieważ jest jedynym identyfikatorem tego interfejsu dla modelu COM. W programie Visual Studio możesz wygenerować identyfikator GUID, przechodząc do pozycji Narzędzia > Tworzenie identyfikatora GUID, aby otworzyć narzędzie Create GUID (Tworzenie identyfikatora GUID).

  6. Dodaj atrybut do interfejsu [InterfaceType] i określ podstawowe interfejsy COM, które interfejs powinien implementować.

  7. Utwórz klasę o nazwie Server , która implementuje IServerelement .

  8. [Guid("<CLSID>")] Dodaj atrybut do klasy z identyfikatorem GUID klasy dla implementowanej klasy COM. Na przykład [Guid("9f35b6f5-2c05-4e7f-93aa-ee087f6e7ab6")]. Podobnie jak w przypadku identyfikatora GUID interfejsu, ten identyfikator GUID musi być unikatowy, ponieważ jest to jedyny identyfikator tego interfejsu do modelu COM.

  9. [ComVisible(true)] Dodaj atrybut do interfejsu i klasy .

Ważne

W przeciwieństwie do platformy .NET Framework platforma .NET Core wymaga określenia identyfikatora CLSID dowolnej klasy, którą chcesz aktywować za pośrednictwem modelu COM.

Generowanie hosta COM

  1. .csproj Otwórz plik projektu i dodaj <EnableComHosting>true</EnableComHosting> go do tagu<PropertyGroup></PropertyGroup>.
  2. Skompiluj projekt.

Wynikowe dane wyjściowe będą miały ProjectName.dllplik , ProjectName.deps.jsonProjectName.runtimeconfig.json i ProjectName.comhost.dll .

Rejestrowanie hosta COM dla modelu COM

Otwórz wiersz polecenia z podwyższonym poziomem uprawnień i uruchom polecenie regsvr32 ProjectName.comhost.dll. Spowoduje to zarejestrowanie wszystkich uwidocznionych obiektów platformy .NET za pomocą modelu COM.

Włączanie regfree COM

  1. .csproj Otwórz plik projektu i dodaj <EnableRegFreeCom>true</EnableRegFreeCom> go do tagu<PropertyGroup></PropertyGroup>.
  2. Skompiluj projekt.

Wynikowe dane wyjściowe będą teraz również miały ProjectName.X.manifest plik. Ten plik jest manifestem side-by-side do użycia z registry-free COM.

Osadzanie bibliotek typów na hoście COM

W przeciwieństwie do platformy .NET Framework nie ma obsługi platformy .NET Core lub .NET 5+ do generowania biblioteki typów MODELU COM (TLB) z zestawu .NET. Wskazówki dotyczą ręcznego pisania pliku IDL lub nagłówka C/C++ dla natywnych deklaracji interfejsów COM. Jeśli zdecydujesz się napisać plik IDL, możesz skompilować go za pomocą kompilatora MIDL zestawu SDK języka Visual C++ w celu utworzenia modułu TLB.

W wersjach .NET 6 i nowszych zestaw .NET SDK obsługuje osadzanie już skompilowanych baz danych TLB na hoście COM w ramach kompilacji projektu.

Aby osadzić bibliotekę typów w aplikacji, wykonaj następujące kroki:

  1. .csproj Otwórz plik projektu i dodaj <ComHostTypeLibrary Include="path/to/typelib.tlb" Id="<id>" /> go wewnątrz tagu<ItemGroup></ItemGroup>.
  2. Zastąp <id> wartość dodatnią liczbą całkowitą. Wartość musi być unikatowa wśród parametrów TLB, które mają być osadzone na hoście COM.
    • Atrybut Id jest opcjonalny, jeśli dodasz go ComHostTypeLibrary tylko do projektu.

Na przykład następujący blok kodu dodaje bibliotekę Server.tlb typów w indeksie 1 do hosta COM:

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

Ładowanie domyślnie AssemblyLoadContext

Podczas aktywacji zestaw zawierający składnik COM jest ładowany oddzielnie AssemblyLoadContext na podstawie ścieżki zestawu. Jeśli istnieje jeden zestaw zapewniający wiele serwerów COM, jest ponownie używany, AssemblyLoadContext tak aby wszystkie serwery z tego zestawu znajdowały się w tym samym kontekście ładowania. Jeśli istnieje wiele zestawów zapewniających serwery COM, zostanie utworzony nowy AssemblyLoadContext dla każdego zestawu, a każdy serwer znajduje się w kontekście ładowania, który odpowiada jego zestawowi.

W programie .NET 8 i nowszych wersjach zestaw może określić, że powinien zostać załadowany w domyślnym AssemblyLoadContextpliku . Aby włączyć ładowanie w kontekście domyślnym, dodaj do projektu następujący element RuntimeHostConfigurationOption :

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

Przykład

W repozytorium dotnet/samples w witrynie GitHub znajduje się w pełni funkcjonalny przykład serwera COM.

Dodatkowe uwagi

Ważne

W programie .NET Framework zestaw "Dowolny procesor" może być używany zarówno przez klientów 32-bitowych, jak i 64-bitowych. Domyślnie w programach .NET Core, .NET 5 i nowszych zestawy "Dowolne procesory" towarzyszą 64-bitowe *.comhost.dll. Z tego powodu mogą być używane tylko przez klientów 64-bitowych. Jest to wartość domyślna, ponieważ oznacza to, co reprezentuje zestaw SDK. To zachowanie jest identyczne ze sposobem publikowania funkcji "samodzielnej": domyślnie używa ona tego, co udostępnia zestaw SDK. Właściwość NETCoreSdkRuntimeIdentifier MSBuild określa bitność *.comhost.dll. Część zarządzana jest faktycznie niezależna od bitów zgodnie z oczekiwaniami, ale towarzyszące im wartości domyślne docelowego zestawu SDK.

Samodzielne wdrożenia składników COM nie są obsługiwane. Obsługiwane są tylko wdrożenia zależne od platformy składników COM.

Ponadto ładowanie programów .NET Framework i .NET Core do tego samego procesu ma ograniczenia diagnostyczne. Głównym ograniczeniem jest debugowanie składników zarządzanych, ponieważ nie można jednocześnie debugować zarówno programu .NET Framework, jak i platformy .NET Core. Ponadto dwa wystąpienia środowiska uruchomieniowego nie współużytkują zarządzanych zestawów. Oznacza to, że nie można współużytkować rzeczywistych typów platformy .NET w dwóch środowiskach uruchomieniowych, a zamiast tego wszystkie interakcje muszą być ograniczone do uwidocznionych kontraktów interfejsu COM.