建立多重實例通用 Windows 應用程式
本主題描述如何建立多實例 通用 Windows 平台 (UWP) 應用程式。
從 Windows 10 版本 1803 (10.0;組建 17134) 之後,您的 UWP 應用程式可以選擇支援多個實例。 如果多執行個體 UWP 應用程式的其中一個執行個體正在執行,而且後續啟用要求成功時,平台將不會啟用現有的執行個體。 反而會建立執行於不同處理序中的新執行個體。
重要
JavaScript 應用程式支援多重實例,但不支援多重實例重新導向。 由於 JavaScript 應用程式不支援多重實例重新導向, 因此 AppInstance 類別不適用於這類應用程式。
選擇加入多重實例行為
如果您要建立新的多實例應用程式,您可以安裝可從 Visual Studio Marketplace 取得的多實例應用程式專案範本.VSIX。 安裝範本之後,這些範本將可在 Visual C# > Windows Universal 下的 [新增專案] 對話方塊中取得(或其他語言 > Visual C++ > Windows 通用)。
注意
不再提供多重實例應用程式項目範本。 VSIX 範本十分方便,因此您必須改為修改現有的專案,如下所述。 請務必將DISABLE_XAML_GENERATED_MAIN常數新增至專案建置符號,因為這樣可防止建置產生預設Main()。 這允許使用特別撰寫的應用程式特定 Main(版本)。
已安裝兩個範本: 多實例 UWP 應用程式,其提供建立多重實例應用程式的範本,以及 多實例重新導向 UWP 應用程式,提供您可以建置的其他邏輯,以啟動新的實例,或選擇性地啟動已啟動的實例。 例如,您可能一次只想要一個實例編輯相同的檔,因此您可以將該檔案開啟的實例帶到前景,而不是啟動新的實例。
這兩個範本都會新增 SupportsMultipleInstances
至 package.appxmanifest
檔案。 請注意命名空間前置 desktop4
詞 和 iot2
:只有以桌面或物聯網 (IoT) 專案為目標的項目支援多重實例。
<Package
...
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
xmlns:iot2="http://schemas.microsoft.com/appx/manifest/iot/windows10/2"
IgnorableNamespaces="uap mp desktop4 iot2">
...
<Applications>
<Application Id="App"
...
desktop4:SupportsMultipleInstances="true"
iot2:SupportsMultipleInstances="true">
...
</Application>
</Applications>
...
</Package>
多重實例啟用重新導向
UWP 應用程式的多重實例支援超越了啟動多個應用程式實例的可能性。 如果您想要選取應用程式的新實例已啟動,或啟動已執行的實例,則允許進行自定義。 例如,如果啟動應用程式來編輯已在另一個實例中編輯的檔案,您可能會想要將啟用重新導向至該實例,而不是開啟另一個已經編輯檔案的實例。
若要查看運作情形,請觀看此影片以建立多重實例 UWP 應用程式。
多重實例重新導向 UWP 應用程式範本會將 新增SupportsMultipleInstances
至 package.appxmanifest 檔案,如上所示,也會將Program.cs (或 Program.cpp,如果您使用 C++ 版本的範本)新增至包含Main()
函式的專案。 重新導向啟用的邏輯會進入函式 Main
。 Program.cs的範本如下所示。
AppInstance.RecommendedInstance 屬性代表這個啟用要求的殼層提供的慣用實例,如果有的話(或null
如果沒有的話)。 如果殼層提供喜好設定,則可以將啟用重新導向至該實例,或選擇時可以忽略它。
public static class Program
{
// This example code shows how you could implement the required Main method to
// support multi-instance redirection. The minimum requirement is to call
// Application.Start with a new App object. Beyond that, you may delete the
// rest of the example code and replace it with your custom code if you wish.
static void Main(string[] args)
{
// First, we'll get our activation event args, which are typically richer
// than the incoming command-line args. We can use these in our app-defined
// logic for generating the key for this instance.
IActivatedEventArgs activatedArgs = AppInstance.GetActivatedEventArgs();
// If the Windows shell indicates a recommended instance, then
// the app can choose to redirect this activation to that instance instead.
if (AppInstance.RecommendedInstance != null)
{
AppInstance.RecommendedInstance.RedirectActivationTo();
}
else
{
// Define a key for this instance, based on some app-specific logic.
// If the key is always unique, then the app will never redirect.
// If the key is always non-unique, then the app will always redirect
// to the first instance. In practice, the app should produce a key
// that is sometimes unique and sometimes not, depending on its own needs.
string key = Guid.NewGuid().ToString(); // always unique.
//string key = "Some-App-Defined-Key"; // never unique.
var instance = AppInstance.FindOrRegisterInstanceForKey(key);
if (instance.IsCurrentInstance)
{
// If we successfully registered this instance, we can now just
// go ahead and do normal XAML initialization.
global::Windows.UI.Xaml.Application.Start((p) => new App());
}
else
{
// Some other instance has registered for this key, so we'll
// redirect this activation to that instance instead.
instance.RedirectActivationTo();
}
}
}
}
Main()
是執行的第一件事。 它會在 OnLaunched 和 OnActivated 之前執行。 這可讓您判斷在執行應用程式的任何其他初始化程序代碼之前,是否要啟動此實例或其他實例。
上述程式代碼會判斷應用程式的現有或新的實例是否已啟動。 金鑰可用來判斷是否有您想要啟動的現有實例。 例如,如果您的應用程式可以啟動以 處理檔案啟用,您可以使用檔名作為密鑰。 然後,您可以檢查應用程式的實例是否已使用該金鑰註冊,並啟動它,而不是開啟新的實例。 這是程式代碼背後的概念: var instance = AppInstance.FindOrRegisterInstanceForKey(key);
如果找到向金鑰註冊的實例,則會啟動該實例。 如果找不到索引鍵,則目前的實例(目前正在執行的 Main
實例)會建立其應用程式物件並開始執行。
背景工作和多重實例
- 跨程式背景工作支援多重實例。 一般而言,每個新的觸發程式都會產生背景工作的新實例(雖然從技術上講,多個背景工作可能會在相同的主機進程中執行)。 不過,會建立背景工作的不同實例。
- 內部背景工作不支援多重實例。
- 背景音訊工作不支援多重實例。
- 當應用程式註冊背景工作時,通常會先檢查工作是否已註冊,然後刪除並重新註冊工作,或不執行任何動作來保留現有的註冊。 這仍然是多實例應用程式的一般行為。 不過,多實例應用程式可能會選擇在每個實例上註冊不同的背景工作名稱。 這會導致相同觸發程式的多個註冊,而且觸發程式引發時將會啟動多個背景工作實例。
- App-services 會針對每個連線啟動個別的 App-Service 背景工作實例。 對於多重實例應用程式而言,這會保持不變,也就是多實例應用程式的每個實例都會取得自己的App-Service背景工作實例。
其他考量
- 以桌面和物聯網(IoT) 專案為目標的 UWP 應用程式支援多重實例。
- 若要避免競爭狀況和爭用問題,多實例應用程式必須採取步驟,以分割/同步存取設定、應用程式本機記憶體,以及任何其他資源(例如使用者檔案、數據存放區等等),這些資源可以在多個實例之間共用。 可以使用標準同步處理機制,例如 Mutex、旗號、事件等等。
- 如果應用程式在其
SupportsMultipleInstances
Package.appxmanifest 檔案中有 ,則其擴展名不需要宣告SupportsMultipleInstances
。 - 如果您新增
SupportsMultipleInstances
至任何其他擴充功能,除了背景工作或應用程式服務之外,裝載擴充功能的應用程式也不會在其 Package.appxmanifest 檔案中宣告SupportsMultipleInstances
,則會產生架構錯誤。 - 應用程式可以使用 其指令清單中的 ResourceGroup 宣告,將多個背景工作分組到相同的主機。 這與多重實例衝突,其中每個啟用都會進入個別的主機。 因此,應用程式無法在其指令清單中宣告
SupportsMultipleInstances
和ResourceGroup
。
範例
如需多重實例啟用重新導向的範例,請參閱 多重實例範例 。
另請參閱
AppInstance.FindOrRegisterInstanceForKeyAppInstance.GetActivatedEventArgsAppInstance.RedirectActivationTo處理應用程式啟用
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應