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 menjelaskan cara menggunakan C#/WinRT untuk menghasilkan assembly proyeksi C# .NET (atau interop) yang berasal dari komponen Windows Runtime C++/WinRT, dan mendistribusikannya sebagai paket NuGet untuk aplikasi .NET.
Pada .NET 6 dan seterusnya, penggunaan 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 yang lebih baru dengan beban kerja pengembangan Platform Windows Universal terinstal. Dalam Detail Instalasi>pengembangan Platform Windows Universal, periksa alat Platform Windows Universal C++ (v14x).
- .NET 8.0 SDK (LTS) atau yang lebih baru.
Kita akan menggunakan Visual Studio 2022 atau yang lebih baru dan .NET 8 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 Windows Runtime C++/WinRT sederhana
Untuk mengikuti panduan ini, Anda harus terlebih dahulu memiliki komponen Windows Runtime C++/WinRT (WRC) untuk menghasilkan rakitan proyeksi C#.
Panduan ini menggunakan SimpleMathComponent WRC dari sampel proyeksi C#/WinRT pada GitHub, yang sudah Anda unduh atau kloning. SimpleMathComponent dibuat dari Windows Runtime Component (C++/WinRT) Visual Studio project template.
Untuk membuka proyek SimpleMathComponent di Visual Studio, buka file \CsWinRT\src\Samples\NetProjectionSample\CppWinRTComponentProjectionSample.sln, yang akan Anda temukan di unduhan atau klon repo.
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 Windows Desktop Compatible diatur ke Yes untuk proyek komponen SimpleMathComponent C++/WinRT Windows Runtime. Untuk melakukannya, di properti proyek untuk SimpleMathComponent, di bawah Properti Konfigurasi>General>Default Proyek, atur properti Kompatibel Desktop Windows ke Ya. Ini memastikan bahwa biner runtime yang benar dimuat agar dapat mengakses 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 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 simpul solusi Anda dan klik Tambahkan>Baru Project.
- 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 8.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 dan pilih Kelola Paket NuGet.
- Di tab Browse, ketik atau tempel Microsoft.Windows. CsWinRT ke dalam kotak pencarian, di hasil pencarian pilih item dengan versi terbaru, lalu klik Install untuk menginstal paket ke SimpleMathProjection project.
Tambahkan ke SimpleMathProjection referensi proyek ke proyek SimpleMathComponent . Di Penjelajah Solusi, klik kanan simpul Dependencies di bawah simpul SimpleMathProjection project, pilih Tambahkan Referensi Project, dan pilih SimpleMathComponent project >OK.
Jangan coba membangun proyek dulu. Kita akan melakukannya di langkah selanjutnya.
Sejauh ini, Penjelajah Solusi Anda seharusnya terlihat seperti ini (nomor versi Anda akan berbeda).
Membangun proyek di luar sumber
Untuk solusi CppWinRTComponentProjectionSample dalam sampel proyeksi C#/WinRT (yang Anda unduh atau kloning dari GitHub, dan sekarang telah terbuka), lokasi output build dikonfigurasi dengan file Directory.Build.props untuk membangun di luar sumber. Itu berarti bahwa file dari output build dihasilkan di luar folder sumber. Sebaiknya Anda membangun dari sumber saat menggunakan alat C#/WinRT. Itu mencegah pengkompilasi C# secara tidak sengaja mengambil semua file *.cs di bawah direktori akar proyek, yang dapat menyebabkan kesalahan jenis duplikat (misalnya saat mengkompilasi untuk beberapa konfigurasi dan/atau platform).
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.
Perbarui elemen
TargetFrameworkuntuk menargetkan versi SDK Windows tertentu. Ini menambahkan dependensi perakitan perangkat lunak yang diperlukan untuk mendukung interoperabilitas dan proyeksi. Sampel ini menargetkan versi SDK Windows 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 memungkinkan aplikasi referensi mendukung versi SDK Windows sebelumnya, Anda juga dapat mengatur propertiTargetPlatformMinimumVersion.<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 perakitan proyeksi dan rakitan implementasi dari komponen.
Gunakan langkah-langkah di bawah ini untuk menambahkan file spesifikasi NuGet (
.nuspec) ke proyek SimpleMathProjection .- Di Penjelajah Solusi, klik kanan SimpleMathProjection node, pilih Tambahkan> Folder Baru, dan beri nama folder nuget.
- Klik kanan folder nuget, pilih Tambahkan>Item 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 untuk memeriksa pengaturan Configuration Manager di Visual Studio, di bawah Build>Configuration Manager. Untuk panduan ini, atur Konfigurasi ke Rilis dan Platform ke x64 untuk solusi tersebut.
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 batalkan pilihan Tampilkan Semua File).
Mereferensikan paket NuGet dalam aplikasi konsol C# .NET 6
Untuk menggunakan SimpleMathComponent dari proyek .NET, Anda cukup menambahkan ke proyek .NET baru referensi ke SimpleMathComponent0.1.0-prerelease.nupkg paket NuGet 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>Project.
- 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, templat proyek AplikasiConsole.
- 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 8.0 (Dukungan jangka panjang), lalu pilih Buat.
Di Penjelajah Solusi, klik dua kali simpul SampleConsoleApp untuk membuka SampleConsoleApp.csproj file proyek, dan edit properti
TargetFrameworkdanPlatformsehingga 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 dalam elemen Project).<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 proyek, Anda mungkin melihat kesalahan seperti: Error 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 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 SDK Aplikasi Windows, dalam proyeksi, Anda perlu menambahkan referensi ke paket SDK Aplikasi Windows 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