Mengekspos komponen .NET Core ke COM

Artikel ini memberi panduan tentang cara mengekspos kelas ke COM dari .NET Core (atau .NET 5+). Tutorial ini akan menunjukkan cara untuk:

  • Mengekspos kelas ke COM dari .NET Core.
  • Buat server COM sebagai bagian dari membangun pustaka .NET Core Anda.
  • Secara otomatis menghasilkan manifes server berdampingan untuk COM Bebas Registri.

Prasyarat

Membuat pustaka

Langkah pertama adalah membuat pustaka.

  1. Buat folder baru, dan di folder tersebut jalankan perintah berikut:

    dotnet new classlib
    
  2. Buka Class1.cs.

  3. Tambahkan using System.Runtime.InteropServices; ke bagian atas file.

  4. Buat antarmuka bernama IServer. Contohnya:

    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. Tambahkan atribut [Guid("<IID>")] ke antarmuka, dengan GUID antarmuka untuk antarmuka COM yang Anda implementasikan. Contohnya,[Guid("fe103d6e-e71b-414c-80bf-982f18f6c1c7")]. Perhatikan bahwa GUID ini harus unik karena ini adalah satu-satunya pengidentifikasi antarmuka ini untuk COM. Di Visual Studio, Anda dapat membuat GUID dengan membuka Alat > Membuat GUID untuk membuka alat Buat GUID.

  6. [InterfaceType] Tambahkan atribut ke antarmuka dan tentukan antarmuka COM dasar apa yang harus diterapkan antarmuka Anda.

  7. Buat kelas bernama Server yang mengimplementasikan IServer.

  8. Tambahkan atribut [Guid("<CLSID>")] ke kelas, dengan GUID pengidentifikasi kelas untuk kelas COM yang Anda terapkan. Contohnya,[Guid("9f35b6f5-2c05-4e7f-93aa-ee087f6e7ab6")]. Seperti halnya GUID antarmuka, GUID ini harus unik karena ini adalah satu-satunya pengidentifikasi antarmuka ini ke COM.

  9. [ComVisible(true)] Tambahkan atribut ke antarmuka dan kelas .

Penting

Tidak seperti dalam .NET Framework, .NET Core mengharuskan Anda menentukan CLSID dari kelas apa pun yang ingin Anda aktifkan melalui COM.

Hasilkan host COM

  1. .csproj Buka file proyek dan tambahkan <EnableComHosting>true</EnableComHosting> di dalam <PropertyGroup></PropertyGroup> tag.
  2. Bangun proyek.

Output yang dihasilkan akan memiliki ProjectName.dll file, ProjectName.deps.json, ProjectName.runtimeconfig.json dan ProjectName.comhost.dll .

Mendaftarkan host COM untuk COM

Buka prompt perintah dengan hak akses administrator dan jalankan regsvr32 ProjectName.comhost.dll. Itu akan mendaftarkan semua objek .NET anda yang terekspos dengan COM.

Jika Anda ingin menyematkan pustaka jenis (TLB), disarankan juga untuk menentukan fungsi menggunakan ComRegisterFunctionAttribute dan ComUnregisterFunctionAttribute. Fungsi-fungsi ini dapat digunakan untuk mendaftar dan membatalkan pendaftaran TLB untuk server COM. Untuk contoh lengkapnya, lihat OutOfProcCOM sampel.

Mengaktifkan RegFree COM

  1. .csproj Buka file proyek dan tambahkan <EnableRegFreeCom>true</EnableRegFreeCom> di dalam <PropertyGroup></PropertyGroup> tag.
  2. Bangun proyek.

Output yang dihasilkan sekarang juga akan memiliki berkas ProjectName.X.manifest. File ini adalah manifes berdampingan untuk digunakan dengan COM Bebas Registri.

Menyematkan pustaka jenis di host COM

Tidak seperti dalam .NET Framework, tidak ada dukungan di .NET Core atau .NET 5+ untuk menghasilkan Com Type Library (TLB) dari rakitan .NET. Panduannya adalah menulis file IDL secara manual atau header C/C++ untuk deklarasi asli antarmuka COM. Jika Anda memutuskan untuk menulis file IDL, Anda dapat mengkompilasinya dengan pengkompilasi MIDL Visual C++ SDK untuk menghasilkan TLB.

Di .NET 6 dan versi yang lebih baru, .NET SDK mendukung penyematan TLB yang sudah dikompilasi ke host COM sebagai bagian dari build proyek Anda.

Untuk menyematkan pustaka tipe ke aplikasi Anda, ikuti langkah-langkah berikut:

  1. .csproj Buka file proyek dan tambahkan <ComHostTypeLibrary Include="path/to/typelib.tlb" Id="<id>" /> di dalam <ItemGroup></ItemGroup> tag.
  2. Ganti <id> dengan nilai bilangan bulat positif. Nilai harus unik di antara TLB yang Anda tentukan untuk disematkan di host COM.
    • Atribut Id bersifat opsional jika Anda hanya menambahkannya ComHostTypeLibrary ke proyek Anda.

Misalnya, blok kode berikut menambahkan Server.tlb pustaka jenis pada indeks 1 ke host COM:

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

Memuat dengan default AssemblyLoadContext

Selama aktivasi, perakitan yang berisi komponen COM dimuat dalam area terpisah berdasarkan lokasi jalur perakitan. Jika ada satu perakitan yang menyediakan beberapa server COM, AssemblyLoadContext digunakan kembali sehingga semua server dari rakitan tersebut berada dalam konteks beban yang sama. Jika ada beberapa rakitan yang menyediakan server COM, yang baru AssemblyLoadContext dibuat untuk setiap rakitan, dan setiap server berada dalam konteks pemuatan yang sesuai dengan rakitannya.

Di .NET 8 dan versi yang lebih baru, rakitan dapat menentukan bahwa harus dimuat dalam default AssemblyLoadContext. Untuk mengaktifkan pemuatan dalam konteks default, tambahkan item RuntimeHostConfigurationOption berikut ke proyek:

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

Sampel

Terdapat contoh server COM yang berfungsi penuh di repositori dotnet/samples di GitHub.

Catatan tambahan

Penting

Dalam .NET Framework, rakitan "CPU apa pun" dapat dikonsumsi oleh klien 32-bit dan 64-bit. Secara default, dalam .NET Core, .NET 5, dan versi yang lebih baru, assembly "Any CPU" disertai dengan *.comhost.dll 64-bit. Karena itu, mereka hanya dapat dikonsumsi oleh klien 64-bit. Itu adalah default karena itulah yang diwakili SDK. Perilaku ini identik dengan cara fitur "mandiri penuh" dipublikasikan: secara default, menggunakan apa yang disediakan SDK. Properti NETCoreSdkRuntimeIdentifier MSBuild menentukan arsitektur bit dari comhost.dll. Bagian terkelola sebenarnya tidak bergantung pada bitness seperti yang diharapkan, tetapi aset asli yang terkait secara default mengarah ke SDK yang ditargetkan.

Penyebaran mandiri dari komponen COM tidak didukung. Hanya penyebaran komponen COM yang bergantung pada kerangka kerja yang didukung.

Mengekspos komponen COM dari C++/CLI proyek melalui properti "EnableComHosting" tidak didukung.

Selain itu, memuat .NET Framework dan .NET Core ke dalam proses yang sama memang memiliki batasan diagnostik. Batasan utama adalah debugging komponen terkelola karena tidak mungkin men-debug .NET Framework dan .NET Core secara bersamaan. Selain itu, kedua instans runtime tidak berbagi rakitan terkelola. Ini berarti bahwa tidak mungkin untuk berbagi jenis .NET aktual di dua runtime dan sebaliknya semua interaksi harus dibatasi untuk kontrak antarmuka COM yang terekspos.

Untuk skenario saat Anda memerlukan alat COM baris-perintah yang mirip dengan alat yang disediakan oleh .NET Framework, lihat proyek komunitas dscom. Proyek ini bukan alat Microsoft, jadi dukungan berasal dari manajer proyek.