Memanggil API Runtime bahasa umum Windows di aplikasi desktop

Topik ini menjelaskan cara menyiapkan proyek aplikasi desktop Anda untuk menggunakan API Windows Runtime (WinRT) yang disediakan oleh OS Windows, dan untuk menambahkan pengalaman Windows 11 dan Windows 10 modern ke aplikasi desktop Anda.

Beberapa API Windows Runtime (WinRT) tidak didukung di aplikasi desktop. Untuk informasi selengkapnya, lihat WINDOWS Runtime API yang tidak didukung di aplikasi desktop.

Mengubah proyek .NET untuk menggunakan WINDOWS Runtime API

Ada beberapa opsi untuk proyek .NET:

  • Mulai dari .NET 6, Anda dapat menentukan Target Framework Moniker (TFM) dalam file proyek Anda untuk mengakses API WinRT. Opsi ini didukung dalam proyek yang menargetkan Windows 10, versi 1809 atau yang lebih baru.
  • Untuk versi .NET yang lebih lama, Anda dapat menginstal Microsoft.Windows.SDK.Contracts paket NuGet untuk menambahkan semua referensi yang diperlukan ke proyek Anda. Opsi ini didukung dalam proyek yang menargetkan Windows 10, versi 1803 atau yang lebih baru.
  • Jika proyek Anda multi-target .NET 6 (atau yang lebih baru) dan versi .NET yang lebih lama, maka Anda dapat mengonfigurasi file proyek untuk menggunakan kedua opsi.

.NET 6 dan yang lebih baru: Gunakan opsi Target Framework Moniker

Opsi ini hanya didukung dalam proyek yang menggunakan .NET 6 (atau yang lebih baru) dan menargetkan Windows 10, versi 1809 atau rilis OS yang lebih baru. Dengan menentukan TFM khusus versi OS Windows dalam file proyek, referensi ditambahkan ke paket penargetan Windows SDK yang sesuai. Untuk informasi latar belakang selengkapnya tentang skenario ini, lihat posting blog Memanggil API Windows di .NET.

  1. Dengan proyek Anda terbuka di Visual Studio, klik kanan proyek Anda di Penjelajah Solusi dan pilih Edit File Proyek. File proyek Anda akan terlihat mirip dengan ini.

    Catatan

    Contoh di bawah ini menunjukkan OutputType dari WinExe, yang menentukan Windows GUI yang dapat dieksekusi (dan mencegah jendela konsol terbuka saat aplikasi berjalan). Jika aplikasi Anda tidak memiliki GUI, OutputType Anda akan memiliki nilai yang berbeda. Anda dapat memanggil API WinRT dari aplikasi Windows GUI, aplikasi konsol, dan pustaka. Selain itu, nilai Anda untuk TargetFramework mungkin tidak sama persis dengan contoh di bawah ini.

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFramework>net5.0</TargetFramework>
      </PropertyGroup>
    </Project>
    
  2. Biarkan semua pengaturan lain apa adanya, ganti nilai elemen TargetFramework dengan salah satu string berikut:

    • net6.0-windows10.0.17763.0: Jika aplikasi Anda menargetkan Windows 10, versi 1809.
    • net6.0-windows10.0.18362.0: Jika aplikasi Anda menargetkan Windows 10, versi 1903.
    • net6.0-windows10.0.19041.0: Jika aplikasi Anda menargetkan Windows 10, versi 2004.
    • net6.0-windows10.0.22000.0: Jika aplikasi Anda menargetkan Windows 11.

    Misalnya, elemen berikut adalah untuk proyek yang menargetkan Windows 10, versi 2004.

    <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
    

    Di versi .NET yang lebih baru, Anda dapat mengganti nilai dengan versi yang relevan, misalnya net6.0-windows10.0.19041.0.

  3. Simpan perubahan Anda dan tutup file proyek.

API WinRT tidak didukung di .NET 6 atau yang lebih baru

Di .NET 6 dan yang lebih baru, ada beberapa API Windows Runtime (WinRT) di namespace Windows.UI yang tidak didukung. Untuk API yang tercantum di bawah ini, versi API yang setara ada di namespace WinUI (Microsoft.UI) (misalnya, Microsoft.UI.Text). API WinRT berikut ini tidak didukung pada .NET 6 dan yang lebih baru:

Mendukung beberapa versi OS Windows

Properti TargetFramework khusus versi OS Windows menentukan versi Windows SDK yang dikompilasi aplikasi Anda. Properti ini menentukan set API yang dapat diakses pada waktu build, dan menyediakan nilai default untuk TargetPlatformVersion dan TargetPlatformMinVersion (jika tidak diatur secara eksplisit). Properti TargetPlatformVersion tidak perlu ditentukan secara eksplisit dalam file proyek, karena secara otomatis ditetapkan oleh versi OS TargetFramework .

TargetPlatformMinVersion dapat diganti menjadi kurang dari TargetPlatformVersion (ditentukan oleh versi di properti TargetFramework). Ini memungkinkan aplikasi untuk berjalan pada versi OS sebelumnya. Misalnya, Anda dapat mengatur hal berikut dalam file proyek Anda untuk mendukung aplikasi Anda ke Windows 10, versi 1809.

<Project Sdk="Microsoft.NET.Sdk">
 <PropertyGroup>
   <OutputType>WinExe</OutputType>
   <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
   <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
 </PropertyGroup>
</Project>

Perhatikan bahwa mengatur TargetPlatformMinVersion ke versi di bawah TargetPlatformVersion menciptakan potensi untuk memanggil API yang tidak tersedia. Saat memanggil API WinRT yang tidak tersedia di semua versi OS yang didukung, sebaiknya jaga panggilan ini dengan pemeriksaan ApiInformation . Untuk informasi selengkapnya, lihat Aplikasi adaptif versi.

Versi .NET yang lebih lama: Instal paket NuGet Microsoft.Windows.SDK.Contracts

Gunakan opsi ini jika aplikasi Anda menggunakan .NET Core 3.x atau .NET Framework. Opsi ini didukung dalam proyek yang menargetkan Windows 10, versi 1803 atau yang lebih baru.

  1. Pastikan referensi paket diaktifkan:

    1. Di Visual Studio, klik Alat -> Pengelola Paket NuGet -> Manajer Paket Pengaturan.
    2. Pastikan PackageReference dipilih untuk Format manajemen paket default.
  2. Dengan proyek Anda terbuka di Visual Studio, klik kanan proyek Anda di Penjelajah Solusi dan pilih Kelola Paket NuGet.

  3. Di jendela Manajer Paket NuGet, pilih tab Telusuri dan cari Microsoft.Windows.SDK.Contracts.

  4. Microsoft.Windows.SDK.Contracts Setelah paket ditemukan, di panel kanan jendela Manajer Paket NuGet pilih Versi paket yang ingin Anda instal berdasarkan versi Windows 10 yang ingin Anda targetkan:

    • 10.0.19041.xxxx: Pilih ini untuk Windows 10, versi 2004.
    • 10.0.18362.xxxx: Pilih ini untuk Windows 10, versi 1903.
    • 10.0.17763.xxxx: Pilih ini untuk Windows 10, versi 1809.
    • 10.0.17134.xxxx: Pilih ini untuk Windows 10, versi 1803.
  5. Klik Pasang.

Mengonfigurasi proyek yang multi-target versi .NET yang berbeda

Jika proyek Anda multi-target .NET 6 (atau yang lebih baru) dan versi yang lebih lama (termasuk .NET Core 3.x dan .NET Framework), maka Anda dapat mengonfigurasi file proyek untuk menggunakan Moniker Kerangka Kerja Target (TFM) untuk secara otomatis menarik referensi API WinRT untuk .NET 6 (atau yang lebih baru), dan menggunakan Microsoft.Windows.SDK.Contracts paket NuGet untuk versi sebelumnya.

  1. Dengan proyek Anda terbuka di Visual Studio, klik kanan proyek Anda di Penjelajah Solusi dan pilih Edit File Proyek. Contoh berikut menunjukkan file proyek untuk aplikasi yang menggunakan .NET Core 3.1.

    Catatan

    Contoh di bawah ini menunjukkan OutputType dari WinExe, yang menentukan Windows GUI yang dapat dieksekusi (dan mencegah jendela konsol terbuka saat aplikasi berjalan). Jika aplikasi Anda tidak memiliki GUI, OutputType Anda akan memiliki nilai yang berbeda. Anda dapat memanggil API WinRT dari aplikasi Windows GUI, aplikasi konsol, dan pustaka. Selain itu, nilai Anda untuk TargetFramework mungkin tidak sama persis dengan contoh di bawah ini.

    <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <UseWindowsForms>true</UseWindowsForms>
      </PropertyGroup>
    </Project>
    
  2. Ganti elemen TargetFramework dalam file dengan elemen TargetFrameworks (perhatikan jamak). Dalam elemen ini, tentukan Monikers Kerangka Kerja Target (TFM) untuk semua versi .NET yang ingin Anda targetkan, dipisahkan oleh titik koma.

    • Untuk .NET 6 atau yang lebih baru, gunakan salah satu Monikers Kerangka Kerja Target (TFM) berikut:
      • net6.0-windows10.0.17763.0: Jika aplikasi Anda menargetkan Windows 10, versi 1809.
      • net6.0-windows10.0.18362.0: Jika aplikasi Anda menargetkan Windows 10, versi 1903.
      • net6.0-windows10.0.19041.0: Jika aplikasi Anda menargetkan Windows 10, versi 2004.
    • Untuk .NET Core 3.x, gunakan netcoreapp3.0 atau netcoreapp3.1.
    • Untuk .NET Framework, gunakan net46.

    Contoh berikut menunjukkan cara multi-target .NET Core 3.1 dan .NET 6 (untuk Windows 10, versi 2004).

    <TargetFrameworks>netcoreapp3.1;net6.0-windows10.0.19041.0</TargetFrameworks>
    
  3. Setelah elemen PropertyGroup, tambahkan elemen PackageReference yang menyertakan pernyataan kondisional yang menginstal Microsoft.Windows.SDK.Contracts paket NuGet untuk versi .NET Core 3.x atau .NET Framework apa pun yang ditargetkan aplikasi Anda. Elemen PackageReference harus merupakan turunan dari elemen ItemGroup . Contoh berikut menunjukkan cara melakukan ini untuk .NET Core 3.1.

    <ItemGroup>
      <PackageReference Condition="'$(TargetFramework)' == 'netcoreapp3.1'"
                        Include="Microsoft.Windows.SDK.Contracts"
                        Version="10.0.19041.0" />
    </ItemGroup>
    

    Setelah selesai, file proyek Anda akan terlihat mirip dengan ini.

    <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFrameworks>netcoreapp3.1;net6.0-windows10.0.19041.0</TargetFrameworks>
        <UseWPF>true</UseWPF>
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Condition="'$(TargetFramework)' == 'netcoreapp3.1'"
                         Include="Microsoft.Windows.SDK.Contracts"
                         Version="10.0.19041.0" />
      </ItemGroup>
    </Project>
    
  4. Simpan perubahan Anda dan tutup file proyek.

Mengubah proyek desktop C++ (Win32) untuk menggunakan WINDOWS Runtime API

Gunakan C++/WinRT untuk menggunakan API WinRT. C++/WinRT adalah proyeksi bahasa C++17 modern yang sepenuhnya standar untuk API WinRT, yang diimplementasikan sebagai pustaka berbasis file header, dan dirancang untuk memberi Anda akses kelas satu ke WINDOWS API modern.

Untuk mengonfigurasi proyek Anda untuk C++/WinRT:

Untuk detail selengkapnya tentang opsi ini, lihat Dukungan Visual Studio untuk C++/WinRT, dan VSIX.

Menambahkan pengalaman Windows 10

Sekarang Anda siap untuk menambahkan pengalaman modern yang menyala ketika pengguna menjalankan aplikasi Anda di Windows 10. Gunakan alur desain ini.

Pertama, putuskan pengalaman apa yang ingin Anda tambahkan

Ada banyak yang bisa dipilih. Misalnya, Anda dapat menyederhanakan alur pesanan pembelian dengan menggunakan API monetisasi, atau perhatian langsung ke aplikasi Anda ketika Anda memiliki sesuatu yang menarik untuk dibagikan, seperti gambar baru yang telah diposting pengguna lain.

Toast notification

Bahkan jika pengguna mengabaikan atau menutup pesan Anda, mereka dapat melihatnya lagi di pusat tindakan, lalu mengklik pesan untuk membuka aplikasi Anda. Ini meningkatkan keterlibatan dengan aplikasi Anda dan memiliki bonus tambahan untuk membuat aplikasi Anda tampak sangat terintegrasi dengan sistem operasi. Kami akan menunjukkan kode untuk pengalaman tersebut sedikit kemudian dalam artikel ini.

Kunjungi dokumentasi UWP untuk lebih banyak ide.

Memutuskan apakah akan meningkatkan atau memperpanjang

Anda akan sering mendengar kami menggunakan istilah yang ditingkatkan dan diperluas, jadi kami akan meluangkan waktu sejenak untuk menjelaskan dengan tepat apa arti masing-masing istilah ini.

Kami menggunakan penyempurnaan istilah untuk menjelaskan API WinRT yang dapat Anda panggil langsung dari aplikasi desktop Anda apakah itu aplikasi yang dipaketkan atau tidak. Ketika Anda telah memilih pengalaman Windows 10, identifikasi API yang perlu Anda buat, lalu lihat apakah API tersebut muncul dalam daftar ini. Ini adalah daftar API yang dapat Anda panggil langsung dari aplikasi desktop Anda. Jika API Anda tidak muncul dalam daftar ini, itu karena fungsionalitas yang terkait dengan API tersebut hanya dapat berjalan dalam proses UWP. Sering kali, ini termasuk API yang merender UWP XAML seperti kontrol peta UWP atau permintaan keamanan Windows Hello.

Catatan

Meskipun API yang merender UWP XAML biasanya tidak dapat dipanggil langsung dari desktop, Anda mungkin dapat menggunakan pendekatan alternatif. Jika Anda ingin menghosting kontrol XAML UWP atau pengalaman visual kustom lainnya, Anda dapat menggunakan Kepulauan XAML (mulai dari Windows 10, versi 1903) dan lapisan Visual (mulai dari Windows 10, versi 1803). Fitur-fitur ini dapat digunakan dalam aplikasi desktop yang dikemas atau tidak dikemas.

Jika Anda telah memilih untuk mengemas aplikasi desktop Anda, maka opsi lain adalah memperluas aplikasi dengan menambahkan proyek UWP ke solusi Anda. Proyek desktop masih merupakan titik masuk aplikasi Anda, tetapi proyek UWP memberi Anda akses ke semua API yang tidak muncul dalam daftar ini. Aplikasi desktop dapat berkomunikasi dengan proses UWP dengan menggunakan layanan aplikasi dan kami memiliki banyak panduan tentang cara mengaturnya. Jika Anda ingin menambahkan pengalaman yang memerlukan proyek UWP, lihat Memperluas dengan komponen UWP.

Kontrak API referensi

Jika Anda dapat memanggil API langsung dari aplikasi desktop Anda, buka browser dan cari topik referensi untuk API tersebut. Di bawah ringkasan API, Anda akan menemukan tabel yang menjelaskan kontrak API untuk API tersebut. Berikut adalah contoh tabel tersebut:

API contract table

Jika Anda memiliki . Aplikasi desktop berbasis NET, tambahkan referensi ke kontrak API tersebut, lalu atur properti Salin Lokal file tersebut ke False. Jika Anda memiliki proyek berbasis C++, tambahkan ke Direktori Sertakan Tambahan Anda, jalur ke folder yang berisi kontrak ini.

Hubungi API untuk menambahkan pengalaman Anda

Berikut adalah kode yang akan Anda gunakan untuk menampilkan jendela pemberitahuan yang kita lihat sebelumnya. API ini muncul dalam daftar ini sehingga Anda dapat menambahkan kode ini ke aplikasi desktop Anda dan menjalankannya sekarang.

using Windows.Foundation;
using Windows.System;
using Windows.UI.Notifications;
using Windows.Data.Xml.Dom;
...

private void ShowToast()
{
    string title = "featured picture of the day";
    string content = "beautiful scenery";
    string image = "https://picsum.photos/360/180?image=104";
    string logo = "https://picsum.photos/64?image=883";

    string xmlString =
    $@"<toast><visual>
       <binding template='ToastGeneric'>
       <text>{title}</text>
       <text>{content}</text>
       <image src='{image}'/>
       <image src='{logo}' placement='appLogoOverride' hint-crop='circle'/>
       </binding>
      </visual></toast>";

    XmlDocument toastXml = new XmlDocument();
    toastXml.LoadXml(xmlString);

    ToastNotification toast = new ToastNotification(toastXml);

    ToastNotificationManager.CreateToastNotifier().Show(toast);
}
#include <sstream>
#include <winrt/Windows.Data.Xml.Dom.h>
#include <winrt/Windows.UI.Notifications.h>

using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::System;
using namespace winrt::Windows::UI::Notifications;
using namespace winrt::Windows::Data::Xml::Dom;

void UWP::ShowToast()
{
    std::wstring const title = L"featured picture of the day";
    std::wstring const content = L"beautiful scenery";
    std::wstring const image = L"https://picsum.photos/360/180?image=104";
    std::wstring const logo = L"https://picsum.photos/64?image=883";

    std::wostringstream xmlString;
    xmlString << L"<toast><visual><binding template='ToastGeneric'>" <<
        L"<text>" << title << L"</text>" <<
        L"<text>" << content << L"</text>" <<
        L"<image src='" << image << L"'/>" <<
        L"<image src='" << logo << L"'" <<
        L" placement='appLogoOverride' hint-crop='circle'/>" <<
        L"</binding></visual></toast>";

    XmlDocument toastXml;

    toastXml.LoadXml(xmlString.str().c_str());

    ToastNotificationManager::CreateToastNotifier().Show(ToastNotification(toastXml));
}
using namespace Windows::Foundation;
using namespace Windows::System;
using namespace Windows::UI::Notifications;
using namespace Windows::Data::Xml::Dom;

void UWP::ShowToast()
{
	Platform::String ^title = "featured picture of the day";
	Platform::String ^content = "beautiful scenery";
	Platform::String ^image = "https://picsum.photos/360/180?image=104";
	Platform::String ^logo = "https://picsum.photos/64?image=883";

	Platform::String ^xmlString =
		L"<toast><visual><binding template='ToastGeneric'>" +
		L"<text>" + title + "</text>" +
		L"<text>"+ content + "</text>" +
		L"<image src='" + image + "'/>" +
		L"<image src='" + logo + "'" +
		L" placement='appLogoOverride' hint-crop='circle'/>" +
		L"</binding></visual></toast>";

	XmlDocument ^toastXml = ref new XmlDocument();

	toastXml->LoadXml(xmlString);

	ToastNotificationManager::CreateToastNotifier()->Show(ref new ToastNotification(toastXml));
}

Untuk mempelajari selengkapnya tentang pemberitahuan, lihat Pemberitahuan toast adaptif dan Interaktif.

Mendukung dasar penginstalan Windows XP, Windows Vista, dan Windows 7/8

Anda dapat memodernisasi aplikasi Untuk Windows 10 tanpa harus membuat cabang baru dan mempertahankan basis kode terpisah.

Jika Anda ingin membangun biner terpisah untuk pengguna Windows 10, gunakan kompilasi bersyariah. Jika Anda lebih suka membuat satu set biner yang Anda sebarkan ke semua pengguna Windows, gunakan pemeriksaan runtime.

Mari kita lihat sekilas setiap opsi.

Kompilasi kondisional

Anda dapat menyimpan satu basis kode dan mengkompilasi sekumpulan biner hanya untuk pengguna Windows 10.

Pertama, tambahkan konfigurasi build baru ke proyek Anda.

Build Configuration

Untuk konfigurasi build tersebut, buat konstanta yang untuk mengidentifikasi kode yang memanggil API WinRT.

Untuk. Proyek berbasis NET, konstanta disebut Konstanta Kompilasi Kondisional.

Conditional Compilation constant

Untuk proyek berbasis C++, konstanta disebut Definisi Preprocessor.

Preprocessor Definition constant

Tambahkan konstanta tersebut sebelum blok kode UWP apa pun.

[System.Diagnostics.Conditional("_UWP")]
private void ShowToast()
{
 ...
}
#if _UWP
void UWP::ShowToast()
{
 ...
}
#endif

Kompiler membuat kode tersebut hanya jika konstanta tersebut ditentukan dalam konfigurasi build aktif Anda.

Pemeriksaan runtime

Anda dapat mengkompilasi satu set biner untuk semua pengguna Windows Anda terlepas dari versi Windows mana yang mereka jalankan. Aplikasi Anda memanggil API WinRT hanya jika pengguna menjalankan aplikasi Anda sebagai aplikasi paket di Windows 10.

Cara term mudah untuk menambahkan pemeriksaan runtime ke kode Anda adalah dengan menginstal paket Nuget ini: Pembantu Jembatan Desktop lalu menggunakan IsRunningAsUWP() metode untuk mengabaikan semua kode yang memanggil API WinRT. Lihat posting blog ini untuk detail selengkapnya: Desktop Bridge - Identifikasi konteks aplikasi.

Temukan jawaban atas pertanyaan Anda

Ada pertanyaan? Tanyakan kami di Stack Overflow. Tim kami memantau tag ini. Anda juga dapat bertanya di forum kami.