Aktivasi yang kaya dengan API siklus hidup aplikasi

Dalam SDK Aplikasi Windows, API siklus hidup aplikasi menghadirkan dukungan untuk perilaku aktivasi kaya gaya UWP ke semua aplikasi, dikemas, dan tidak dikemas sama. Rilis pertama ini berfokus pada menghadirkan jenis aktivasi yang paling umum digunakan ke aplikasi yang tidak dikemas, dan rilis mendatang bertujuan untuk mendukung lebih banyak jenis aktivasi 44 UWP.

Mendukung aktivasi yang kaya memerlukan dua langkah:

  • Beri tahu sistem bahwa aplikasi Anda mendukung satu atau beberapa jenis aktivasi yang kaya.
  • Menerima dan memproses payload aktivasi kaya yang diterima aplikasi Anda saat diaktifkan.

Prasyarat

Untuk menggunakan API siklus hidup aplikasi di SDK Aplikasi Windows:

  1. Unduh dan instal rilis terbaru SDK Aplikasi Windows. Untuk informasi selengkapnya, lihat Menginstal alat untuk SDK Aplikasi Windows.
  2. Ikuti instruksi untuk Membuat proyek WinUI 3 pertama Anda atau untuk menggunakan SDK Aplikasi Windows dalam proyek yang ada.

Detail aktivasi untuk aplikasi yang tidak dikemas

Versi SDK Aplikasi Windows saat ini mendukung empat jenis aktivasi yang paling umum untuk membuka kemasan aplikasi. Jenis aktivasi ini didefinisikan oleh enum ExtendedActivationKind .

Jenis aktivasi Deskripsi
Launch Aktifkan aplikasi dari baris perintah, saat pengguna mengklik dua kali ikon aplikasi, atau secara terprogram melalui ShellExecute atau CreateProcess.
File Aktifkan aplikasi yang telah mendaftar untuk jenis file saat file jenis dibuka melalui ShellExecute, Launcher.LaunchFileAsync, atau baris perintah.
Protocol Aktifkan aplikasi yang telah mendaftar untuk protokol saat string protokol tersebut dijalankan melalui ShellExecute, Launcher.LaunchUriAsync, atau baris perintah.
StartupTask Aktifkan aplikasi saat pengguna masuk ke Windows, baik karena kunci registri, atau karena pintasan di folder startup terkenal.

Setiap jenis aplikasi yang tidak dikemas mengambil argumen baris perintahnya dengan cara yang berbeda. Misalnya, aplikasi C++ Win32 mengharapkan untuk menerima argumen aktivasi yang akan diteruskan dalam WinMain bentuk string (meskipun mereka juga memiliki opsi untuk memanggil GetCommandLineW). namun, Formulir Windows aplikasi harus memanggil Environment.GetCommandLineArgs, karena argumen tidak akan secara otomatis diteruskan ke aplikasi tersebut.

Detail aktivasi untuk aplikasi paket

Aplikasi paket yang menggunakan SDK Aplikasi Windows mendukung semua 44 jenis aktivasi UWP. Setiap jenis aktivasi memiliki implementasi IActivatedEventArgs yang sesuai yang berisi properti yang relevan dengan jenis aktivasi tertentu.

Aplikasi yang dipaketkan akan selalu menerima argumen peristiwa aktivasi di penanganan aktivitas AppInstance.Diaktifkan , dan juga memiliki opsi untuk memanggil AppInstance.GetActivatedEventArgs.

Pendaftaran aktivasi

Semua aplikasi mendukung Launch jenis aktivasi secara default. Tidak seperti UWP, jenis aktivasi SDK Aplikasi Windows Launch mencakup peluncuran baris perintah. Aplikasi dapat mendaftar untuk jenis aktivasi tambahan dengan beberapa cara.

  • Aplikasi yang tidak dipaketkan yang menggunakan SDK Aplikasi Windows dapat mendaftar (dan membatalkan pendaftaran) untuk jenis aktivasi tambahan melalui API siklus hidup aplikasi di SDK Aplikasi Windows.
  • Aplikasi yang tidak dipaketkan dapat terus mendaftar untuk jenis aktivasi tambahan menggunakan metode tradisional menulis kunci registri.
  • Aplikasi paket dapat mendaftar untuk jenis aktivasi tambahan melalui entri dalam manifes aplikasi mereka.

Pendaftaran aktivasi adalah per pengguna. Jika aplikasi Anda diinstal untuk beberapa pengguna, Anda harus mendaftarkan ulang aktivasi untuk setiap pengguna.

Contoh

Daftar untuk aktivasi kaya

Meskipun aplikasi dapat memanggil API pendaftaran kapan saja, skenario yang paling umum adalah memeriksa pendaftaran pada startup aplikasi.

Contoh ini menunjukkan bagaimana aplikasi yang tidak dikemas dapat menggunakan metode statis berikut dari kelas ActivationRegistrationManager untuk mendaftar beberapa jenis aktivasi saat aplikasi diluncurkan:

Contoh ini juga menunjukkan cara menggunakan fungsi MddBootstrapInitialize dan MddBootstrapShutdown untuk menginisialisasi dan membersihkan referensi ke paket kerangka kerja SDK Aplikasi Windows. Semua aplikasi yang tidak dikemas harus melakukan ini untuk menggunakan API yang disediakan oleh SDK Aplikasi Windows. Untuk informasi selengkapnya, lihat Menggunakan runtime SDK Aplikasi Windows untuk aplikasi yang dikemas dengan lokasi eksternal atau tidak dikemas.

Catatan

Contoh ini mendaftarkan asosiasi dengan tiga jenis file gambar sekaligus. Ini nyaman, tetapi hasilnya sama dengan mendaftarkan setiap jenis file satu per satu; mendaftarkan jenis gambar baru tidak menimpa pendaftaran sebelumnya. Namun, jika aplikasi mendaftarkan ulang jenis file yang sudah terdaftar dengan serangkaian kata kerja yang berbeda, kumpulan kata kerja sebelumnya akan ditimpa untuk jenis file tersebut.

const UINT32 majorMinorVersion{ WINDOWSAPPSDK_RELEASE_MAJORMINOR };
PCWSTR versionTag{ WINDOWSAPPSDK_RELEASE_VERSION_TAG_W };
const PACKAGE_VERSION minVersion{ WINDOWSAPPSDK_RUNTIME_VERSION_UINT64 };
WCHAR szExePath[MAX_PATH]{};
WCHAR szExePathAndIconIndex[MAX_PATH + 8]{};

int APIENTRY wWinMain(
    _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // Initialize Windows App SDK framework package for unpackaged apps.
    HRESULT hr{ MddBootstrapInitialize(majorMinorVersion, versionTag, minVersion) };
    if (FAILED(hr))
    {
        wprintf(L"Error 0x%X in MddBootstrapInitialize(0x%08X, %s, %hu.%hu.%hu.%hu)\n",
            hr, majorMinorVersion, versionTag, minVersion.Major, 
            minVersion.Minor, minVersion.Build, minVersion.Revision);
        return hr;
    }

    // Get the current executable filesystem path, so we can
    // use it later in registering for activation kinds.
    GetModuleFileName(NULL, szExePath, MAX_PATH);
    wcscpy_s(szExePathAndIconIndex, szExePath);
    wcscat_s(szExePathAndIconIndex, L",1");

    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_CLASSNAME, szWindowClass, MAX_LOADSTRING);
    RegisterWindowClass(hInstance);
    if (!InitInstance(hInstance, nCmdShow))
    {
        return FALSE;
    }

    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    // Uninitialize Windows App SDK.
    MddBootstrapShutdown();
    return (int)msg.wParam;
}

void RegisterForActivation()
{
    OutputMessage(L"Registering for rich activation");

    // Register one or more supported filetypes, specifying 
    // an icon (specified by binary file path plus resource index),
    // a display name to use in Shell and Settings,
    // zero or more verbs for the File Explorer context menu,
    // and the path to the EXE to register for activation.
    hstring myFileTypes[3] = { L".foo", L".foo2", L".foo3" };
    hstring verbs[2] = { L"view", L"edit" };
    ActivationRegistrationManager::RegisterForFileTypeActivation(
        myFileTypes,
        szExePathAndIconIndex,
        L"Contoso File Types",
        verbs,
        szExePath
    );

    // Register a URI scheme for protocol activation,
    // specifying the scheme name, icon, display name and EXE path.
    ActivationRegistrationManager::RegisterForProtocolActivation(
        L"foo",
        szExePathAndIconIndex,
        L"Contoso Foo Protocol",
        szExePath
    );

    // Register for startup activation.
    // As we're registering for startup activation multiple times,
    // and this is a multi-instance app, we'll get multiple instances
    // activated at startup.
    ActivationRegistrationManager::RegisterForStartupActivation(
        L"ContosoStartupId",
        szExePath
    );

    // If we don't specify the EXE, it will default to this EXE.
    ActivationRegistrationManager::RegisterForStartupActivation(
        L"ContosoStartupId2",
        L""
    );
}

Mendapatkan argumen peristiwa aktivasi yang kaya

Setelah diaktifkan, aplikasi harus mengambil argumen peristiwa aktivasinya. Dalam contoh ini, aplikasi yang tidak dipaket memanggil metode AppInstance.GetActivatedEventArgs untuk mendapatkan argumen peristiwa untuk peristiwa aktivasi lalu menggunakan properti AppActivationArguments.Kind untuk mengambil args peristiwa untuk berbagai jenis aktivasi.

Catatan

Aplikasi Win32 biasanya mendapatkan argumen baris perintah sangat awal metodenya WinMain . Demikian pula, aplikasi ini harus memanggil AppInstance.GetActivatedEventArgs di tempat yang sama di mana mereka sebelumnya akan menggunakan parameter yang disediakan lpCmdLine atau disebut GetCommandLineW.

void GetActivationInfo()
{
    AppActivationArguments args = AppInstance::GetCurrent().GetActivatedEventArgs();
    ExtendedActivationKind kind = args.Kind();
    if (kind == ExtendedActivationKind::Launch)
    {
        ILaunchActivatedEventArgs launchArgs = 
            args.Data().as<ILaunchActivatedEventArgs>();
        if (launchArgs != NULL)
        {
            winrt::hstring argString = launchArgs.Arguments().c_str();
            std::vector<std::wstring> argStrings = split_strings(argString);
            OutputMessage(L"Launch activation");
            for (std::wstring s : argStrings)
            {
                OutputMessage(s.c_str());
            }
        }
    }
    else if (kind == ExtendedActivationKind::File)
    {
        IFileActivatedEventArgs fileArgs = 
            args.Data().as<IFileActivatedEventArgs>();
        if (fileArgs != NULL)
        {
            IStorageItem file = fileArgs.Files().GetAt(0);
            OutputFormattedMessage(
                L"File activation: %s", file.Name().c_str());
        }
    }
    else if (kind == ExtendedActivationKind::Protocol)
    {
        IProtocolActivatedEventArgs protocolArgs = 
            args.Data().as<IProtocolActivatedEventArgs>();
        if (protocolArgs != NULL)
        {
            Uri uri = protocolArgs.Uri();
            OutputFormattedMessage(
                L"Protocol activation: %s", uri.RawUri().c_str());
        }
    }
    else if (kind == ExtendedActivationKind::StartupTask)
    {
        IStartupTaskActivatedEventArgs startupArgs = 
            args.Data().as<IStartupTaskActivatedEventArgs>();
        if (startupArgs != NULL)
        {
            OutputFormattedMessage(
                L"Startup activation: %s", startupArgs.TaskId().c_str());
        }
    }
}

Membatalkan Pendaftaran

Contoh ini menunjukkan bagaimana aplikasi yang tidak dikemas dapat membatalkan pendaftaran untuk jenis aktivasi tertentu secara dinamis, menggunakan metode statis berikut dari kelas ActivationRegistrationManager :

Catatan

Saat membatalkan pendaftaran untuk aktivasi startup, aplikasi harus menggunakan taskId yang sama dengan yang digunakan saat awalnya didaftarkan.

void UnregisterForActivation()
{
    OutputMessage(L"Unregistering for rich activation");
    
    // Unregister one or more registered filetypes.
    try
    {
        hstring myFileTypes[3] = { L".foo", L".foo2", L".foo3" };
        ActivationRegistrationManager::UnregisterForFileTypeActivation(
            myFileTypes,
            szExePath
        );
    }
    catch (...)
    {
        OutputMessage(L"Error unregistering file types");
    }

    // Unregister a protocol scheme.
    ActivationRegistrationManager::UnregisterForProtocolActivation(
        L"foo",
        L"");

    // Unregister for startup activation.
    ActivationRegistrationManager::UnregisterForStartupActivation(
        L"ContosoStartupId");
    ActivationRegistrationManager::UnregisterForStartupActivation(
        L"ContosoStartupId2");
}