Bagikan melalui


Migrasi fungsionalitas siklus hidup aplikasi

Topik ini berisi panduan migrasi di area siklus hidup aplikasi.

API penting

Ringkasan perbedaan API dan/atau fitur

aplikasi Platform Windows Universal (UWP) di-instans tunggal secara default; aplikasi SDK Aplikasi Windows (WinUI 3) multi-instans secara default.

Aplikasi UWP memiliki metode Aplikasi seperti OnFileActivated, OnSearchActivated, OnActivated, dan OnBackgroundActivated yang secara implisit memberi tahu Anda bagaimana aplikasi diaktifkan; Dalam aplikasi SDK Aplikasi Windows, di App.OnLaunched (atau dalam metode apa pun), panggil (AppInstance.GetActivatedEventArgs) untuk mengambil arg peristiwa yang diaktifkan, dan periksa untuk menentukan bagaimana aplikasi diaktifkan.

Lihat juga baris Tugas latar belakang dalam tabel di topik Apa yang didukung saat bermigrasi dari UWP ke WinUI 3.

Aplikasi instans tunggal

aplikasi Platform Windows Universal (UWP) di-instans tunggal secara default (Anda dapat memilih untuk mendukung beberapa instans—lihat Membuat aplikasi UWP multi-instans).

Jadi cara aplikasi UWP instans tunggal berulah adalah bahwa waktu kedua (dan berikutnya) yang Anda luncurkan, instans Anda saat ini diaktifkan. Katakanlah misalnya bahwa di aplikasi UWP Anda, Anda telah menerapkan fitur asosiasi jenis file. Jika dari File Explorer Anda membuka file (dari jenis aplikasi yang telah mendaftarkan asosiasi jenis file)—dan aplikasi Anda sudah berjalan—maka instans yang sudah berjalan diaktifkan.

SDK Aplikasi Windows (WinUI 3) aplikasi, di sisi lain, multi-instans secara default. Jadi, secara default, waktu kedua (dan berikutnya) Anda meluncurkan aplikasi SDK Aplikasi Windows (WinUI 3), instans baru aplikasi diluncurkan. Jika misalnya aplikasi SDK Aplikasi Windows (WinUI 3) mengimplementasikan asosiasi jenis file, dan dari File Explorer Anda membuka file (dari jenis yang tepat) saat aplikasi tersebut sudah berjalan, maka secara default instans baru aplikasi diluncurkan.

Jika Anda ingin aplikasi SDK Aplikasi Windows (WinUI 3) Anda di-instans tunggal seperti aplikasi UWP Anda, maka Anda dapat mengambil alih perilaku default yang dijelaskan di atas. Anda akan menggunakan AppInstance.FindOrRegisterForKey dan AppInstance.IsCurrent untuk menentukan apakah instans saat ini adalah instans utama. Jika tidak, maka Anda akan memanggil AppInstance.RedirectActivationToAsync untuk mengalihkan aktivasi ke instans utama yang sudah berjalan, lalu keluar dari instans saat ini (tanpa membuat atau mengaktifkan jendela utamanya).

Untuk informasi selengkapnya, lihat Instancing aplikasi dengan API siklus hidup aplikasi.

Penting

Kode yang ditunjukkan di bawah ini berfungsi seperti yang diharapkan asalkan Anda menargetkan arsitektur x64 . Itu berlaku untuk C# dan C++/WinRT.

Instancing tunggal di Main atau wWinMain

Yang terbaik adalah memeriksa kebutuhan untuk mengalihkan aktivasi sedini mungkin dalam eksekusi aplikasi Anda. Untuk alasan itu, kami sarankan Anda melakukan logika instancing tunggal di fungsi Utama aplikasi Anda (atau wWinMain untuk C++/WinRT). Bagian ini memperlihatkan kepada Anda caranya.

Biasanya, fungsi Utama aplikasi Anda dibuat secara otomatis oleh sistem build, dan ditempatkan ke dalam file tersembunyi. Jadi langkah pertama adalah mengonfigurasi proyek Anda untuk tidak menghasilkan fungsi tersebut secara otomatis. Untuk melakukannya, Anda menentukan simbol DISABLE_XAML_GENERATED_MAIN di properti proyek.

Instruksi untuk C#

Buka Properti> (pilih Semua Konfigurasi dan Semua Platform)> Bangun>simbol kompilasi Bersyarkat, dan tempelkan simbol DISABLE_XAML_GENERATED_MAIN.

Karena kami baru saja mencegah proyek membuat fungsi Utama secara otomatis, proyek tidak akan dibangun saat ini. Jadi langkah kedua dan terakhir adalah mengimplementasikan versi fungsi itu sendiri dalam file kode sumber.

Tambahkan item proyek baru jenis Kelas ke proyek, dan beri nama Program.cs. Di dalam Program.cs, ganti kode class Program {} dengan implementasi Anda sendiri. Untuk contoh kode yang akan digunakan, lihat Program.cs dalam sampel AppLifecycle.

Instruksi untuk C++/WinRT

Buka Properti> (pilih Semua Konfigurasi dan Semua Platform)> Properti>Konfigurasi C/C++>Preprocessor Preprocessor>Definitions, Edit nilai, dan tambahkan simbol DISABLE_XAML_GENERATED_MAIN.

Karena kami baru saja mencegah proyek membuat fungsi wWinMain secara otomatis, proyek tidak akan dibangun saat ini. Jadi langkah kedua dan terakhir adalah mengimplementasikan versi fungsi itu sendiri dalam file kode sumber.

Tambahkan referensi ke paket NuGet Microsoft.Windows.ImplementationLibrary, dan perbarui file kode sumber dan App.xaml.cpp proyek pch.h Anda. Untuk contoh kode yang akan digunakan, lihat sampel AppLifecycle. Pastikan untuk mengubah namespace layanan winrt::CppWinUiDesktopInstancing::implementation::App agar sesuai dengan proyek tertentu Anda).

Untuk mengatasi "kesalahan C2872: 'Microsoft': simbol ambigu", ubah using namespace Microsoft::UI::Xaml; ke using namespace winrt::Microsoft::UI::Xaml;. Dan buat perubahan using serupa tambahan pada arahan.

Instancing tunggal di Application.OnLaunched

Alternatif untuk menggunakan Main atau wWinMain adalah melakukan logika instancing tunggal Anda dalam metode Application.OnLaunched dari kelas Aplikasi Anda.

Penting

Melakukan pekerjaan ini di Application.OnLaunched dapat menyederhanakan aplikasi Anda. Namun, banyak tergantung pada apa lagi yang dilakukan aplikasi Anda. Jika Anda akan akhirnya mengalihkan, dan kemudian mengakhiri instans saat ini, maka Anda harus menghindari melakukan pekerjaan lemparan jauh (atau bahkan pekerjaan yang perlu diurungkan secara eksplisit). Dalam kasus seperti itu, Application.OnLaunched mungkin terlambat, dan Anda mungkin lebih suka melakukan pekerjaan di fungsi Utama atau wWinMain aplikasi Anda.

// App.xaml.cs in a Windows App SDK (WinUI 3) app
...
protected override async void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
    // If this is the first instance launched, then register it as the "main" instance.
    // If this isn't the first instance launched, then "main" will already be registered,
    // so retrieve it.
    var mainInstance = Microsoft.Windows.AppLifecycle.AppInstance.FindOrRegisterForKey("main");

    // If the instance that's executing the OnLaunched handler right now
    // isn't the "main" instance.
    if (!mainInstance.IsCurrent)
    {
        // Redirect the activation (and args) to the "main" instance, and exit.
        var activatedEventArgs =
            Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs();
        await mainInstance.RedirectActivationToAsync(activatedEventArgs);
        System.Diagnostics.Process.GetCurrentProcess().Kill();
        return;
    }

    m_window = new MainWindow();
    m_window.Activate();
}
// pch.h in a Windows App SDK (WinUI 3) app
...
#include <winrt/Microsoft.Windows.AppLifecycle.h>
...

// App.xaml.h
...
struct App : AppT<App>
{
    ...
    winrt::fire_and_forget OnLaunched(Microsoft::UI::Xaml::LaunchActivatedEventArgs const&);
    ...
}

// App.xaml.cpp
...
using namespace winrt;
using namespace Microsoft::Windows::AppLifecycle;
...
winrt::fire_and_forget App::OnLaunched(LaunchActivatedEventArgs const&)
{
    // If this is the first instance launched, then register it as the "main" instance.
    // If this isn't the first instance launched, then "main" will already be registered,
    // so retrieve it.
    auto mainInstance{ AppInstance::FindOrRegisterForKey(L"main") };

    // If the instance that's executing the OnLaunched handler right now
    // isn't the "main" instance.
    if (!mainInstance.IsCurrent())
    {
        // Redirect the activation (and args) to the "main" instance, and exit.
        auto activatedEventArgs{ AppInstance::GetCurrent().GetActivatedEventArgs() };
        co_await mainInstance.RedirectActivationToAsync(activatedEventArgs);
        ::ExitProcess(0);
        co_return;
    }

    window = make<MainWindow>();
    window.Activate();
}

Atau, Anda dapat memanggil AppInstance.GetInstances untuk mengambil kumpulan objek AppInstance yang sedang berjalan. Jika jumlah elemen dalam koleksi tersebut lebih besar dari 1, maka instans utama Anda sudah berjalan, dan Anda harus mengalihkan ke itu.

Asosiasi jenis file

Dalam proyek SDK Aplikasi Windows, untuk menentukan titik ekstensi untuk asosiasi jenis file, Anda membuat pengaturan yang sama dalam file Anda Package.appxmanifest seperti yang Anda lakukan untuk proyek UWP. Berikut adalah pengaturan tersebut.

Buka Package.appxmanifest. Di Deklarasi, pilih Asosiasi Tipe File, dan klik Tambahkan. Atur properti berikut.

Nama tampilan: Nama MyFile: jenis File myfile: .myf

Untuk mendaftarkan asosiasi jenis file, buat aplikasi, luncurkan, dan tutup.

Perbedaannya datang dalam kode imperatif. Di aplikasi UWP, Anda menerapkan App::OnFileActivated untuk menangani aktivasi file. Tetapi dalam aplikasi SDK Aplikasi Windows, Anda menulis kode di App::OnLaunched untuk memeriksa jenis aktivasi yang diperluas (ExtendedActivationKind) dari args peristiwa yang diaktifkan (AppInstance.GetActivatedEventArgs), dan melihat apakah aktivasi adalah aktivasi file.

Catatan

Jangan gunakan objek Microsoft.UI.Xaml.LaunchActivatedEventArgs yang diteruskan ke App::OnLaunched untuk menentukan jenis aktivasi, karena melaporkan "Luncurkan" tanpa syarat.

Jika aplikasi Anda memiliki navigasi, maka Anda akan memiliki kode navigasi di App::OnLaunched, dan Anda mungkin ingin menggunakan kembali logika tersebut. Untuk informasi selengkapnya, lihat Apakah saya perlu menerapkan navigasi halaman?.

// App.xaml.cs in a Windows App SDK app
...
using Microsoft.Windows.AppLifecycle;
...
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
    var activatedEventArgs = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs();
    if (activatedEventArgs.Kind == Microsoft.Windows.AppLifecycle.ExtendedActivationKind.File)
    {
        ...
    }
    ...
}
// pch.h in a Windows App SDK app
...
#include <winrt/Microsoft.Windows.AppLifecycle.h>

// App.xaml.cpp
...
using namespace Microsoft::Windows::AppLifecycle;
...
void App::OnLaunched(LaunchActivatedEventArgs const&)
{
    auto activatedEventArgs{ AppInstance::GetCurrent().GetActivatedEventArgs() };
    if (activatedEventArgs.Kind() == ExtendedActivationKind::File)
    {
        ...
    }
    ...
}

OnActivated, OnBackgroundActivated, dan metode penanganan aktivasi lainnya

Di aplikasi UWP, untuk mengambil alih berbagai cara di mana aplikasi Anda dapat diaktifkan, Anda dapat mengambil alih metode yang sesuai di kelas Aplikasi Anda, seperti OnFileActivated, OnSearchActivated, atau OnActivated yang lebih umum.

Dalam aplikasi SDK Aplikasi Windows, di App.OnLaunched (atau sebenarnya kapan saja) Anda dapat memanggil (AppInstance.GetActivatedEventArgs) untuk mengambil args peristiwa yang diaktifkan, dan memeriksanya untuk menentukan bagaimana aplikasi diaktifkan.

Lihat bagian Asosiasi jenis file di atas untuk detail selengkapnya dan contoh kode. Anda dapat menerapkan teknik yang sama untuk jenis aktivasi apa pun yang ditentukan oleh enum ExtendedActivationKind.