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.
Windows menyediakan beberapa teknologi yang memungkinkan aplikasi Anda menyediakan fungsionalitas ke aplikasi lain atau menggunakan add-in pihak ketiga. Artikel ini membandingkan opsi ekstensibilitas yang tersedia untuk aplikasi desktop SDK Aplikasi Windows.
Gambaran umum opsi ekstensibilitas
| Teknologi | Deskripsi | Identitas paket diperlukan | Sistem Operasi Minimum |
|---|---|---|---|
| Layanan aplikasi | Komunikasi permintaan/respons antar aplikasi melalui AppServiceConnection |
Yes | Windows 10 1607 |
| Ekstensi aplikasi | Model plug-in — aplikasi host menemukan konten dari paket ekstensi | Yes | Windows 10 1607 |
| Ekstensi paket | Ekstensibilitas tingkat paket yang lebih luas dengan uap17:PackageExtension |
Yes | Windows 11 |
| Paket opsional | Paket konten tambahan yang melengkapi aplikasi utama | Yes | Windows 10 1709 |
| Paket sumber daya | Aset bahasa, skala, dan aksesibilitas yang dipisahkan berdasarkan pasar | Yes | Windows 10 |
Memilih teknologi yang tepat
Gunakan layanan aplikasi saat
- Anda memerlukan komunikasi dua arah antara aplikasi terpisah.
- Aplikasi konsumen mengirimkan permintaan dan menunggu respons.
- Anda ingin mengekspos antarmuka seperti API ke aplikasi lain.
Contoh: Layanan terjemahan yang dapat dipanggil aplikasi lain untuk menerjemahkan teks.
Gunakan ekstensi aplikasi saat
- Aplikasi Anda memerlukan model plug-in di mana pihak ketiga menyediakan konten, tema, atau add-in.
- Ekstensi ditemukan pada runtime dari paket yang diinstal.
- Ekstensi menyediakan data atau konfigurasi, bukan kode yang dapat dieksekusi (eksekusi kode harus menggunakan layanan aplikasi).
Contoh: Editor gambar yang menemukan paket filter dari paket ekstensi yang diinstal.
Gunakan ekstensi paket saat
- Anda memerlukan ekstensibilitas tingkat paket yang lebih luas pada Windows 11.
- Ekstensi memerlukan akses ke lebih banyak konten paket daripada yang dimungkinkan oleh model
PublicFolder.
Gunakan paket opsional saat
- Anda memiliki konten tambahan (DLC, fitur premium) yang didistribusikan sebagai paket terpisah.
- Konten ditulis oleh penerbit yang sama.
Pola arsitektur
Layanan aplikasi dengan pendeteksian ekstensi
Gabungkan ekstensi aplikasi dengan layanan aplikasi untuk arsitektur plug-in lengkap:
- Aplikasi host Anda menggunakan
AppExtensionCataloguntuk menemukan ekstensi yang diinstal. - Setiap ekstensi mendeklarasikan properti yang menjelaskan kemampuannya.
- Saat pengguna mengaktifkan ekstensi, aplikasi host terhubung ke layanan aplikasi ekstensi untuk komunikasi dua arah.
┌─────────────────┐ ┌──────────────────┐
│ Host app │ │ Extension app │
│ │ │ │
│ AppExtension │◄────►│ AppExtension │
│ Catalog │ │ declaration │
│ │ │ │
│ AppService │◄────►│ AppService │
│ Connection │ │ provider │
└─────────────────┘ └──────────────────┘
Perluasan konten saja
Untuk skenario yang lebih sederhana di mana ekstensi menyediakan konten statis (tema, templat, file data):
- Aplikasi host menemukan ekstensi melalui
AppExtensionCatalog. - Ini membaca file dari ekstensi
PublicFolder. - Tidak diperlukan layanan aplikasi.
Perbedaan dari ekstensibilitas UWP
Teknologi ekstensibilitas yang dijelaskan di sini berfungsi dengan cara yang sama dalam SDK Aplikasi Windows aplikasi desktop seperti yang mereka lakukan di UWP, dengan satu persyaratan: identitas paket MSIX. Semua fitur ekstensibilitas mengandalkan manifes paket untuk deklarasi dan katalog paket untuk penemuan.
Jika aplikasi desktop Anda tidak dikemas, Anda tidak dapat menggunakan teknologi ekstensibilitas ini. Pertimbangkan pendekatan alternatif seperti:
- Antarmuka plug-in berbasis COM
- Penemuan ekstensi berbasis sistem file
- Pipa bernama atau mekanisme IPC lainnya
Penemuan plugin berbasis file untuk aplikasi yang tidak dikemas
Untuk aplikasi WinUI 3 yang tidak dikemas, Anda dapat menerapkan sistem plugin menggunakan .NET AssemblyLoadContext untuk memuat ekstensi dari folder yang diketahui:
public class PluginLoader
{
private readonly string _pluginDirectory;
public PluginLoader(string pluginDirectory)
{
_pluginDirectory = pluginDirectory;
}
public IEnumerable<T> LoadPlugins<T>() where T : class
{
if (!Directory.Exists(_pluginDirectory))
yield break;
foreach (var dll in Directory.GetFiles(_pluginDirectory, "*.dll"))
{
var context = new PluginLoadContext(dll);
var assembly = context.LoadFromAssemblyPath(Path.GetFullPath(dll));
foreach (var type in assembly.GetTypes()
.Where(t => typeof(T).IsAssignableFrom(t) && !t.IsAbstract))
{
if (Activator.CreateInstance(type) is T plugin)
yield return plugin;
}
}
}
}
// Custom AssemblyLoadContext to isolate plugin dependencies
public class PluginLoadContext : AssemblyLoadContext
{
private readonly AssemblyDependencyResolver _resolver;
public PluginLoadContext(string pluginPath) : base(isCollectible: true)
{
_resolver = new AssemblyDependencyResolver(pluginPath);
}
protected override Assembly? Load(AssemblyName assemblyName)
{
var path = _resolver.ResolveAssemblyToPath(assemblyName);
return path != null ? LoadFromAssemblyPath(path) : null;
}
}
Warning
Memuat rakitan dari disk tanpa validasi adalah risiko keamanan. Dalam produksi, verifikasi tanda tangan rakitan (seperti Authenticode) sebelum memuat, batasi izin ACL direktori plugin, dan pertimbangkan untuk menjalankan plugin dalam proses terpisah dengan hak istimewa yang dikurangi.
Definisikan sebuah kontrak antarmuka bersama dalam assembly terpisah yang direferensikan oleh host dan plugin:
// Contoso.App.Contracts (shared assembly)
public interface IPluginExtension
{
string Name { get; }
string Description { get; }
void Execute(IServiceProvider services);
}
Note
Menggunakan isCollectible: true dalam AssemblyLoadContext memungkinkan Anda untuk membongkar plugin pada runtime. Pendekatan ini menghindari masalah pembuatan versi yang dapat ditimbulkan oleh MEF (Managed Extensibility Framework) pada aplikasi desktop.
Konten terkait
Windows developer