本主題包含應用程式生命週期領域的移轉指南。
重要 API
- AppInstance 類別
- Application.OnLaunched 方法
- AppInstance.GetActivatedEventArgs 方法
- ExtendedActivationKind 枚舉
API 和/或功能差異摘要
預設情況下,通用 Windows 平台 (UWP) 應用程式是單一執行個體; 預設情況下,Windows 應用程式 SDK (WinUI 3) 應用程式是多執行個體。
UWP 應用程式具有 App 方法,例如 OnFileActivated、OnSearchActivated、OnActivated 和 OnBackgroundActivated,可隱含地告訴您應用程式如何啟動;在 Windows 應用程式 SDK 應用程式中,在 App.OnLaunched (或任何方法中),呼叫 (AppInstance.GetActivatedEventArgs) 以擷取啟動的事件自變數,並檢查它們以判斷應用程式如何啟動。
另請參閱從 UWP 移轉到 WinUI 3 時支援的內容主題中表格中的背景任務行。
單一執行個體應用程式
通用 Windows 平台 (UWP) 應用程式預設為單一執行個體 (您可以選擇支援多個執行個體—請參閱建立多執行個體 UWP 應用程式)。
因此,單一執行個體的 UWP 應用程式的行為方式是,當您第二次(或之後)啟動時,當前的執行個體將被激活。 例如,在 UWP 應用程式中,您已實作檔案類型關聯功能。 如果您從檔案總管開啟一個檔案(此檔案類型已由應用程式註冊關聯),且您的應用程式已在執行中,那麼該已執行的實例將會被啟動。
另一方面,Windows 應用程式 SDK (WinUI 3) 應用程式預設為多重執行個體。 因此,根據預設,當您第二次(及後續)啟動 Windows 應用程式 SDK (WinUI 3) 時,將會啟動新的應用程式執行個體。 例如,如果 Windows 應用程式 SDK (WinUI 3) 應用程式實作檔類型關聯,而且從檔案總管開啟檔案 (正確類型)時,該應用程式已在執行中,則預設會啟動應用程式的新執行個體。
如果您想要讓 Windows 應用程式 SDK (WinUI 3) 應用程式像 UWP 應用程式一樣採用單一執行個體模式,則可以自訂上述的預設行為。 您將使用 AppInstance.FindOrRegisterForKey 和 AppInstance.IsCurrent 來判斷目前的執行個體是否為主要執行個體。 如果不是,則您將呼叫 AppInstance.RedirectActivationToAsync,將啟動重定向至已在運行的主要執行個體,然後退出當前執行個體(不建立或啟動其主視窗)。
如需詳細資訊,請參閱 使用應用程式生命週期 API 的應用程式實例。
重要
下列程式代碼會如預期般運作,前提是您以 x64 架構為目標。 這同時適用於 C# 和 C++/WinRT。
Main 或 wWinMain 中的單一執行個體
最好在應用程式的執行過程中儘早檢查重新導向的啟用需求。 基於這個理由,我們建議您在應用程式的 Main 函式中(或適用於 C++/WinRT 的 wWinMain 函式)呼叫單一實例化邏輯。 本章節將示範方式。
一般而言,應用程式的 Main 函式是由建置系統自動產生,並放入隱藏的檔案中。 因此,第一個步驟是將項目設定為不要自動產生該函式。 若要這樣做,您可以在專案屬性中定義符號 DISABLE_XAML_GENERATED_MAIN。
C# 的使用說明
轉到屬性> (選擇 All Configurations 和 All Platforms) >Build>Conditional compilation symbols,並貼上符號 DISABLE_XAML_GENERATED_MAIN。
因為我們剛剛防止專案自動產生 Main 函式,因此專案目前不會建置。 因此,第二個步驟和最後一個步驟是在原始程式碼檔案中實作我們自己版本的該函式。
將類別類型的新專案專案新增至專案,並將它命名為Program.cs。 在 Program.cs 中,用您自己的實作替換程式代碼 class Program {}。 如需要使用的程式代碼範例,請參閱 Program.csAppLifecycle 範例。
C++/WinRT 的說明
前往 Properties> (選擇 All Configurations 和 All Platforms) >Configuration Properties>C/C++>Preprocessor>Preprocessor Definitions、Edit 值,並加入符號 DISABLE_XAML_GENERATED_MAIN。
因為我們剛剛防止專案自動產生 wWinMain 函式,因此專案目前不會建置。 因此,第二個步驟和最後一個步驟是在原始程式碼檔案中實作我們自己版本的該函式。
新增對 Microsoft.Windows.ImplementationLibrary NuGet 套件的引用,並更新專案的 pch.h 和 App.xaml.cpp 原始碼檔案。 如需要使用的程式代碼範例,請參閱 AppLifecycle 範例。 請務必變更 winrt::CppWinUiDesktopInstancing::implementation::App 中的命名空間,以符合您的特定專案。
若要解決「錯誤 C2872:'Microsoft':不明確的符號」,請變更 using namespace Microsoft::UI::Xaml; 為 using namespace winrt::Microsoft::UI::Xaml;。 對 using 指令進行任何其他類似的變更。
Application.OnLaunched 中的單一執行個體
使用 Main 或 wWinMain 的另一個選擇是在 App 類別的 Application.OnLaunched 方法中執行單一執行個體邏輯。
重要
在 Application.OnLaunched 中執行這項工作可以簡化您的應用程式。 不過,很多都取決於您的應用程式正在做什麼。 如果您最終要重新導向並終止當前的任務,那麼您應避免做任何可以丟棄的工作(或甚至需要明確還原的工作)。 在這種情況下,Application.OnLaunched 可能太晚,而且您可能偏好在應用程式的 Main 或 wWinMain 函式中執行工作。
// 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();
}
或者,您可以呼叫 AppInstance.GetInstances 來擷取正在執行的 AppInstance 物件的集合。 如果該集合中的元素數目大於 1,則您的主要執行個體已經執行中,您應該重新導向至該執行個體。
檔案類型關聯
在 Windows 應用程式 SDK 專案中,若要指定檔案類型關聯的擴充點,請在 Package.appxmanifest 檔案中進行與 UWP 專案相同的設定。 以下是這些設定。
開啟 [Package.appxmanifest]。 在聲明中,選擇檔案類型關聯,然後按一下新增。 設定下列屬性。
顯示名稱:MyFile 名稱:myfile 檔類型:.myf
若要註冊檔類型關聯,請建置應用程式、啟動它,然後關閉它。
差異在於命令式程序代碼。 在UWP應用程式中,您會實作 App::OnFileActivated 以處理檔案啟用。 但是在 Windows 應用程式 SDK 應用程式中,您在
注意
請勿使用 Microsoft.UI.Xaml.LaunchActivatedEventArgs 傳遞至 App::OnLaunched 對象來判斷啟用種類,因為會無條件回報「啟動」。
如果您的應用程式具有導航功能,那麼您已經在 App::OnLaunched 中擁有導航程式碼,並且您可能想要重新使用該邏輯。 如需詳細資訊,請參閱是否需要實作頁面導覽?。
// 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 和其他啟用處理方法。
在 UWP 應用程式中,若要覆寫可以啟動應用程式的各種方式,您可以在 App 類別上覆寫對應的方法,例如 OnFileActivated、OnSearchActivated 或更一般 OnActivated。
在 Windows App SDK 應用程式中,不論是在 App.OnLaunched 還是任何時刻,您都可以呼叫 AppInstance.GetActivatedEventArgs 來擷取啟動的事件引數,並檢查它們以判斷應用程式是如何啟動的。
如需詳細資訊和程式代碼範例,請參閱上面的檔案類型關聯一節。 您可以對 ExtendedActivationKind 枚舉中指定的任何啟用類型應用相同的技術。
相關主題
- Windows 應用程式 SDK 和支援的 Windows 版本
- 利用應用程式生命週期 API 進行應用程式執行個體化
- 我需要實作頁面導覽嗎?