Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dalam topik ini, kita membahas penggunaan C#/WinRT untuk menghasilkan assembly proyeksi C# .NET (atau interop) dari komponen C++/WinRT Windows Runtime, dan mendistribusikannya sebagai paket NuGet untuk aplikasi .NET.
Di .NET 6 dan yang lebih baru, konsumsi file metadata Windows (WinMD) tidak lagi didukung (lihat Dukungan bawaan untuk WinRT dihapus dari .NET). Sebagai gantinya, alat C#/WinRT dapat digunakan untuk menghasilkan rakitan proyeksi untuk file WinMD apa pun, yang kemudian memungkinkan konsumsi komponen WinRT dari aplikasi .NET. Rakitan proyeksi juga dikenal sebagai rakitan interop. Panduan ini menunjukkan kepada Anda cara melakukan hal berikut:
- Gunakan paket C#/WinRT untuk menghasilkan proyeksi C# dari komponen C++/WinRT.
- Distribusikan komponen, bersama dengan rakitan proyeksi, sebagai paket NuGet.
- Gunakan paket NuGet dari aplikasi konsol .NET.
Prasyarat
Panduan ini dan sampel yang sesuai memerlukan alat dan komponen berikut:
- Visual Studio 2022 (atau Visual Studio 2019) dengan paket pengembangan Universal Windows Platform yang terinstal. Dalam Detail Penginstalan>pengembangan Universal Windows Platform, periksa opsi alat C++ (v14x) untuk Universal Windows Platform.
- .NET 6.0 SDK atau yang lebih baru.
Visual Studio 2019 saja. Ekstensi C++/WinRT VSIX, yang memberi Anda templat proyek C++/WinRT di Visual Studio. Templat proyek dibangun di Visual Studio 2022.
Kami akan menggunakan Visual Studio 2022 dan .NET 6 dalam panduan ini.
Penting
Selain itu, Anda harus mengunduh atau mengkloning kode sampel untuk topik ini dari sampel proyeksi C#/WinRT di GitHub. Kunjungi CsWinRT, dan klik tombol Kode hijau untuk mendapatkan URL git clone. Pastikan untuk membaca file README.md sebagai contoh.
Membuat komponen C++/WinRT Windows Runtime sederhana
Untuk mengikuti panduan ini, Anda harus terlebih dahulu memiliki komponen C++/WinRT Windows Runtime (WRC) untuk menghasilkan rakitan proyeksi C#.
Panduan ini menggunakan SimpleMathComponent WRC dari sampel proyeksi C#/WinRT di GitHub, yang sudah Anda unduh atau kloning. SimpleMathComponent dibuat dari templat proyek Visual Studio Komponen Runtime Windows (C++/WinRT) (yang dilengkapi dengan Visual Studio 2022, atau dengan ekstensi C++/WinRT VSIX).
Untuk membuka proyek SimpleMathComponent di Visual Studio, buka \CsWinRT\src\Samples\NetProjectionSample\CppWinRTComponentProjectionSample.sln file, yang akan Anda temukan di unduhan atau klon repositori.
Kode dalam proyek ini menyediakan fungsionalitas untuk operasi matematika dasar yang ditunjukkan dalam file header di bawah ini.
// SimpleMath.h
...
namespace winrt::SimpleMathComponent::implementation
{
struct SimpleMath: SimpleMathT<SimpleMath>
{
SimpleMath() = default;
double add(double firstNumber, double secondNumber);
double subtract(double firstNumber, double secondNumber);
double multiply(double firstNumber, double secondNumber);
double divide(double firstNumber, double secondNumber);
};
}
Anda dapat mengonfirmasi bahwa properti Kompatibel Desktop Windows diatur ke Ya untuk proyek komponen Windows Runtime C++/WinRT SimpleMathComponent. Untuk melakukannya, dalam properti proyek untuk SimpleMathComponent, di bawah Properti Konfigurasi>Umum>Default Proyek, atur properti Windows Desktop Compatible ke nilai Ya. Ini memastikan bahwa file biner runtime yang benar dimuat untuk menjalankan aplikasi desktop .NET.
halaman properti yang Kompatibel dengan Desktop
Untuk langkah-langkah lebih rinci tentang membuat komponen C++/WinRT dan membuat file WinMD, lihat komponen Windows Runtime dengan C++/WinRT.
Nota
Jika Anda menerapkan IInspectable::GetRuntimeClassName di komponen Anda, maka harus mengembalikan nama kelas WinRT yang valid. Karena C#/WinRT menggunakan string nama kelas untuk interop, nama kelas runtime yang salah akan memunculkan InvalidCastException.
Menambahkan proyeksi ke solusi komponen
Pertama, dengan solusi CppWinRTComponentProjectionSample yang masih terbuka di Visual Studio, hapus proyek SimpleMathProjection dari solusi tersebut. Kemudian hapus dari sistem file Anda folder SimpleMathProjection (atau ganti namanya jika Mau). Langkah-langkah tersebut diperlukan agar Anda dapat mengikuti panduan ini langkah demi langkah.
Tambahkan proyek pustaka C# baru ke solusi Anda.
- Di Penjelajah Solusi, klik kanan pada node solusi Anda dan klik Tambah>Proyek Baru.
- Dalam kotak dialog Tambahkan proyek baru , ketik Pustaka Kelas di kotak pencarian. Pilih C# dari daftar bahasa, lalu pilih Windows dari daftar platform. Pilih templat proyek C# yang disebut hanya Pustaka Kelas (tanpa awalan maupun akhiran), dan klik Berikutnya.
- Beri nama proyek baru SimpleMathProjection. Lokasi harus sudah diatur ke folder
\CsWinRT\src\Samples\NetProjectionSampleyang sama dengan yang terdapat di folder SimpleMathComponent; tetapi pastikan bahwa demikian. Lalu, klik Berikutnya. - Pada halaman Informasi tambahan , pilih .NET 6.0 (Dukungan jangka panjang), lalu pilih Buat.
Hapus file Class1.cs stub dari proyek.
Gunakan langkah-langkah di bawah ini untuk menginstal paket C#/WinRT NuGet.
- Di Penjelajah Solusi, klik kanan proyek SimpleMathProjection Anda dan pilih Kelola Paket NuGet.
- Di tab Telusuri , ketik atau tempelkan Microsoft.Windows.CsWinRT ke dalam kotak pencarian, di hasil pencarian pilih item dengan versi terbaru, lalu klik Instal untuk menginstal paket ke dalam proyek SimpleMathProjection .
Tambahkan ke SimpleMathProjection referensi proyek ke proyek SimpleMathComponent . Di Penjelajah Solusi, klik kanan simpul Dependensi di bawah simpul proyek SimpleMathProjection, pilih Tambahkan Referensi Proyek, dan pilih proyek SimpleMathComponent>OK.
Jangan coba membangun proyek dulu. Kita akan melakukannya di langkah selanjutnya.
Sejauh ini, Solution Explorer Anda seharusnya terlihat mirip dengan ini (nomor versi Anda mungkin berbeda).
Membangun proyek di luar sumber
Untuk solusi CppWinRTComponentProjectionSample
Meskipun ini sudah dikonfigurasi untuk solusi CppWinRTComponentProjectionSample, ikuti langkah-langkah di bawah ini untuk berlatih melakukan konfigurasi sendiri.
Untuk mengonfigurasi solusi Anda untuk membangun dari sumber:
Dengan solusi CppWinRTComponentProjectionSample masih terbuka, klik kanan pada simpul solusi, dan pilih Tambahkan>Item Baru. Pilih item File XML , dan beri nama Directory.Build.props (tanpa
.xmlekstensi). Klik Ya untuk menimpa file yang ada.Ganti konten Directory.Build.props dengan konfigurasi di bawah ini.
<Project> <PropertyGroup> <BuildOutDir>$([MSBuild]::NormalizeDirectory('$(SolutionDir)', '_build', '$(Platform)', '$(Configuration)'))</BuildOutDir> <OutDir>$([MSBuild]::NormalizeDirectory('$(BuildOutDir)', '$(MSBuildProjectName)', 'bin'))</OutDir> <IntDir>$([MSBuild]::NormalizeDirectory('$(BuildOutDir)', '$(MSBuildProjectName)', 'obj'))</IntDir> </PropertyGroup> </Project>Simpan dan tutup file Directory.Build.props .
Edit file proyek untuk menjalankan C#/WinRT
Sebelum dapat memanggil cswinrt.exe alat untuk menghasilkan rakitan proyeksi, Anda harus terlebih dahulu mengedit file proyek untuk menentukan beberapa properti proyek.
Di Penjelajah Solusi, klik dua kali simpul SimpleMathProjection untuk membuka file proyek di editor.
TargetFrameworkPerbarui elemen untuk menargetkan versi Windows SDK tertentu. Ini menambahkan dependensi perakitan perangkat lunak yang diperlukan untuk mendukung interoperabilitas dan proyeksi. Sampel ini menargetkan versi Windows SDK net6.0-windows10.0.19041.0 (juga dikenal sebagai Windows 10, versi 2004). AturPlatformelemen ke AnyCPU sehingga rakitan proyeksi yang dihasilkan dapat direferensikan dari arsitektur aplikasi apa pun. Untuk mengizinkan aplikasi referensi mendukung versi Windows SDK sebelumnya, Anda juga dapat mengaturTargetPlatformMinimumVersionproperti .<PropertyGroup> <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework> <!-- Set Platform to AnyCPU to allow consumption of the projection assembly from any architecture. --> <Platform>AnyCPU</Platform> </PropertyGroup>Nota
Untuk panduan ini dan kode sampel terkait, solusi dibuat untuk x64 dan Rilis. Perhatikan bahwa proyek SimpleMathProjection dikonfigurasi untuk membangun AnyCPU untuk semua konfigurasi arsitektur solusi.
Tambahkan elemen kedua
PropertyGroup(segera setelah yang pertama) yang mengatur beberapa properti C#/WinRT.<PropertyGroup> <CsWinRTIncludes>SimpleMathComponent</CsWinRTIncludes> <CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir> </PropertyGroup>Berikut adalah beberapa detail tentang pengaturan dalam contoh ini:
- Properti
CsWinRTIncludesmenentukan namespace mana yang akan diproyeksikan. - Properti
CsWinRTGeneratedFilesDirmengatur direktori output tempat file sumber proyeksi dihasilkan. Properti ini ditetapkan keOutDir, yang didefinisikan dalam Directory.Build.props dari bagian di atas.
- Properti
Simpan dan tutup file SimpleMathProjection.csproj , dan klik muat ulang proyek jika perlu.
Membuat paket NuGet dengan proyeksi
Untuk mendistribusikan rakitan proyeksi untuk pengembang aplikasi .NET, Anda dapat secara otomatis membuat paket NuGet saat membangun solusi dengan menambahkan beberapa properti proyek tambahan. Untuk target .NET, paket NuGet perlu menyertakan rakitan proyeksi dan rakitan implementasi dari komponen.
Gunakan langkah-langkah di bawah ini untuk menambahkan file spesifikasi NuGet (
.nuspec) ke proyek SimpleMathProjection .- Di Solution Explorer, klik kanan pada simpul SimpleMathProjection, pilih Tambah>Folder Baru, dan beri nama folder tersebut nuget.
- Klik kanan folder nuget
, pilih TambahkanItem Baru , pilih file XML , dan beri nama SimpleMathProjection.nuspec .
Di Penjelajah Solusi, klik dua kali simpul SimpleMathProjection untuk membuka file proyek di editor. Tambahkan grup properti berikut ke SimpleMathProjection.csproj yang sekarang terbuka (segera setelah dua elemen yang ada
PropertyGroup) untuk menghasilkan paket secara otomatis. Properti ini menentukanNuspecFiledan direktori untuk menghasilkan paket NuGet.<PropertyGroup> <GeneratedNugetDir>.\nuget\</GeneratedNugetDir> <NuspecFile>$(GeneratedNugetDir)SimpleMathProjection.nuspec</NuspecFile> <OutputPath>$(GeneratedNugetDir)</OutputPath> <GeneratePackageOnBuild>true</GeneratePackageOnBuild> </PropertyGroup>Nota
Jika Anda lebih suka membuat paket secara terpisah, maka Anda juga dapat memilih untuk menjalankan
nuget.exealat dari baris perintah. Untuk informasi selengkapnya tentang membuat paket NuGet, lihat Membuat paket menggunakan CLI nuget.exe.Buka file SimpleMathProjection.nuspec untuk mengedit properti pembuatan paket, dan tempelkan kode berikut. Cuplikan di bawah ini adalah contoh spesifikasi NuGet untuk mendistribusikan SimpleMathComponent ke beberapa kerangka kerja target. Perhatikan bahwa rakitan proyeksi, SimpleMathProjection.dll, ditentukan alih-alih SimpleMathComponent.winmd untuk target
lib\net6.0-windows10.0.19041.0\SimpleMathProjection.dll. Perilaku ini baru di .NET 6 dan yang lebih baru, dan diaktifkan oleh C#/WinRT. Rakitan implementasi,SimpleMathComponent.dll, juga harus didistribusikan, dan akan dimuat pada runtime.<?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd"> <metadata> <id>SimpleMathComponent</id> <version>0.1.0-prerelease</version> <authors>Contoso Math Inc.</authors> <description>A simple component with basic math operations</description> <dependencies> <group targetFramework="net6.0-windows10.0.19041.0" /> <group targetFramework=".NETCoreApp3.0" /> <group targetFramework="UAP10.0" /> <group targetFramework=".NETFramework4.6" /> </dependencies> </metadata> <files> <!--Support .NET 6, .NET Core 3, UAP, .NET Framework 4.6, C++ --> <!--Architecture-neutral assemblies--> <file src="..\..\_build\AnyCPU\Release\SimpleMathProjection\bin\SimpleMathProjection.dll" target="lib\net6.0-windows10.0.19041.0\SimpleMathProjection.dll" /> <file src="..\..\_build\x64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.winmd" target="lib\netcoreapp3.0\SimpleMathComponent.winmd" /> <file src="..\..\_build\x64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.winmd" target="lib\uap10.0\SimpleMathComponent.winmd" /> <file src="..\..\_build\x64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.winmd" target="lib\net46\SimpleMathComponent.winmd" /> <!--Architecture-specific implementation DLLs should be copied into RID-relative folders--> <file src="..\..\_build\x64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.dll" target="runtimes\win10-x64\native\SimpleMathComponent.dll" /> <!--To support x86 and Arm64, build SimpleMathComponent for those other architectures and uncomment the entries below.--> <!--<file src="..\..\_build\Win32\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.dll" target="runtimes\win10-x86\native\SimpleMathComponent.dll" />--> <!--<file src="..\..\_build\arm64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.dll" target="runtimes\win10-arm64\native\SimpleMathComponent.dll" />--> </files> </package>Nota
SimpleMathComponent.dll, rakitan implementasi untuk komponen, khusus arsitektur. Jika Anda mendukung platform lain (misalnya, x86 atau Arm64), maka Anda harus terlebih dahulu membangun SimpleMathComponent untuk platform yang diinginkan, dan menambahkan file rakitan ini ke folder RELATIF RID yang sesuai. Rakitan proyeksi SimpleMathProjection.dll dan komponen SimpleMathComponent.winmd keduanya netral arsitektur.
Simpan dan tutup file yang baru saja Anda edit.
Bangun solusi untuk menghasilkan proyeksi dan paket NuGet
Sebelum membangun solusi, pastikan memeriksa pengaturan
Pada titik ini Anda sekarang dapat membangun solusi. Klik kanan pada simpul solusi Anda dan pilih Bangun Solusi. Ini pertama-tama akan membangun proyek SimpleMathComponent , lalu proyek SimpleMathProjection . Komponen WinMD dan rakitan implementasi (SimpleMathComponent.winmd dan SimpleMathComponent.dll), file sumber proyeksi, dan rakitan proyeksi (SimpleMathProjection.dll), semuanya akan dihasilkan di bawah direktori output _build . Anda juga akan dapat melihat paket NuGet yang dihasilkan, SimpleMathComponent0.1.0-prerelease.nupkg, di bawah folder \SimpleMathProjection\nuget .
Penting
Jika salah satu file yang disebutkan di atas tidak dihasilkan, buat solusi untuk kedua kalinya. Anda mungkin juga perlu menutup dan membuka kembali solusi tersebut sebelum menyusun ulang.
Anda mungkin perlu menutup dan membuka kembali solusi agar .nupkg muncul di Visual Studio seperti yang diilustrasikan (atau cukup pilih lalu batal pilih Tampilkan Semua File).
Mereferensikan paket NuGet dalam aplikasi konsol C# .NET 6
Untuk menggunakan SimpleMathComponent dari proyek .NET, Anda dapat dengan mudah menambahkan referensi pada proyek .NET baru ke paket NuGet SimpleMathComponent0.1.0-prerelease.nupkg yang kami buat di bagian sebelumnya. Langkah-langkah berikut menunjukkan cara melakukannya dengan membuat aplikasi Konsol sederhana dalam solusi terpisah.
Gunakan langkah-langkah di bawah ini untuk membuat solusi baru yang berisi proyek Aplikasi Konsol C# (membuat proyek ini dalam solusi baru memungkinkan Anda memulihkan paket SimpleMathComponent NuGet secara independen).
Penting
Kami akan membuat proyek aplikasi konsol
baru ini di folder , yang dapat Anda temukan pada sampel proyeksi C#/WinRT . - Dalam instans baru Visual Studio, pilih File >Baru>Proyek.
- Dalam kotak dialog Buat proyek baru , cari templat proyek Aplikasi Konsol . Pilih templat proyek C# yang disebut hanya Aplikasi Konsol (tanpa awalan atau akhiran), dan klik Berikutnya. Jika Anda menggunakan Visual Studio 2019, maka templat proyeknya adalah Aplikasi Konsol.
- Beri nama proyek baru SampleConsoleApp, atur lokasinya ke folder
\CsWinRT\src\Samples\NetProjectionSampleyang sama dengan folder SimpleMathComponent dan folder SimpleMathProjection, dan klik Next. - Pada halaman Informasi tambahan , pilih .NET 6.0 (Dukungan jangka panjang), lalu pilih Buat.
Di Penjelajah Solusi, klik dua kali simpul SampleConsoleApp untuk membuka file proyek SampleConsoleApp.csproj , dan edit
TargetFrameworkproperti danPlatformsehingga terlihat seperti yang ditunjukkan dalam daftar berikut. Tambahkan elemenPlatformjika tidak ada.<PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework> <Platform>x64</Platform> </PropertyGroup>Dengan file proyek SampleConsoleApp.csproj masih terbuka, berikutnya kita akan menambahkan referensi ke proyek SampleConsoleApp paket SimpleMathComponent NuGet. Untuk memulihkan
SimpleMathComponent NuGet saat membangun proyek, Anda dapat menggunakan propertidengan jalur ke folder nuget dalam solusi komponen Anda. Salin konfigurasi berikut, dan tempelkan ke SampleConsoleApp.csproj (di Projectdalam elemen ).<PropertyGroup> <RestoreSources> https://api.nuget.org/v3/index.json; ../SimpleMathProjection/nuget </RestoreSources> </PropertyGroup> <ItemGroup> <PackageReference Include="SimpleMathComponent" Version="0.1.0-prerelease" /> </ItemGroup>Penting
Jalur
RestoreSourcesuntuk paket SimpleMathComponent yang ditunjukkan di atas ditetapkan ke../SimpleMathProjection/nuget. Jalur tersebut benar asalkan Anda mengikuti langkah-langkah dalam panduan ini, sehingga proyek SimpleMathComponent dan SampleConsoleApp keduanya berada di folder yang sama (NetProjectionSamplefolder, dalam hal ini). Jika Anda telah melakukan sesuatu yang berbeda, maka Anda harus menyesuaikan jalur tersebut dengan sesuai. Atau, Anda dapat menambahkan umpan paket NuGet lokal ke solusi Anda.Edit file Program.cs untuk menggunakan fungsionalitas yang disediakan oleh SimpleMathComponent.
var x = new SimpleMathComponent.SimpleMath(); Console.WriteLine("Adding 5.5 + 6.5 ..."); Console.WriteLine(x.add(5.5, 6.5).ToString());Simpan dan tutup file yang baru saja Anda edit, dan buat dan jalankan aplikasi konsol. Anda akan melihat output di bawah ini.
Masalah yang diketahui
- Saat membangun proyeksi, Anda mungkin melihat kesalahan seperti: Kesalahan MSB3271 Ada ketidakcocokan antara arsitektur prosesor proyek yang dibangun "MSIL" dan arsitektur prosesor, "x86", dari file implementasi "..\SimpleMathComponent.dll" untuk ".. \SimpleMathComponent.winmd". Ketidakcocokan ini dapat menyebabkan kegagalan runtime. Pertimbangkan untuk mengubah arsitektur prosesor yang ditargetkan dari proyek Anda melalui Configuration Manager sehingga dapat menyelaraskan arsitektur prosesor antara file proyek dan implementasi Anda, atau pilih file winmd dengan file implementasi yang memiliki arsitektur prosesor yang cocok dengan arsitektur prosesor yang ditargetkan dari proyek Anda. Untuk mengatasi kesalahan ini, tambahkan properti berikut ke file proyek pustaka C# Anda:
<PropertyGroup> <!-- Workaround for MSB3271 error on processor architecture mismatch --> <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch> </PropertyGroup>
Pertimbangan lebih lanjut
Rakitan proyeksi C# (atau interop) yang kami tunjukkan cara membuat dalam topik ini cukup sederhana—tidak memiliki dependensi pada komponen lain. Tetapi untuk menghasilkan proyeksi C# untuk komponen C++/WinRT yang memiliki referensi ke jenis Windows App SDK, dalam proyeksi, Anda perlu menambahkan referensi ke paket Windows App SDK NuGet. Jika ada referensi seperti itu yang hilang, maka Anda akan melihat kesalahan seperti "Jenis <T> tidak dapat ditemukan".
Hal lain yang kita lakukan dalam topik ini adalah mendistribusikan proyeksi sebagai paket NuGet. itu saat ini diperlukan.
Sumber Daya
Windows developer