共用方式為


建立多執行個體通用 Windows 應用程式

本主題介紹如何建立多執行個體通用 Windows 平台 (UWP) 應用程式。

從 Windows 10 版本 1803 (10.0;內部版本 17134) 開始,你的 UWP 應用程式可以選擇支援多個執行個體。 如果多執行個體 UWP 應用程式的其中一個執行個體正在執行,而且後續啟用要求成功時,平台將不會啟用現有的執行個體。 反而會建立執行於不同處理序中的新執行個體。

重要

JavaScript 應用程式支援多重執行個體,但不支援多重執行個體重新導向。 由於 JavaScript 應用程式不支援多重執行個體重新導向,因此 AppInstance 類別不適用於這類應用程式。

選擇加入多重執行個體行為

如果您要建立新的多執行個體應用程式,您可以安裝可從 Visual Studio Marketplace 取得的 Multi-Instance App Project Templates.VSIX。 安裝範本後,它們將在 Visual C#> Windows Universal (或其他語言> Visual C++> Windows Universal) 下的新專案對話方塊中可用。

注意

不再提供多重實例應用程式項目範本。 VSIX 範本十分方便,因此您必須改為修改現有的專案,如下所述。 請務必將DISABLE_XAML_GENERATED_MAIN常數新增至專案建置符號,因為這樣可防止建置產生預設Main()。 這允許使用特別撰寫的應用程式特定 Main(版本)。

安裝了兩個範本:多執行個體 UWP 應用程式 (提供用於建立多執行個體應用程式的範本) 和多執行個體重定向 UWP 應用程式 (提供附加邏輯,您可以在該邏輯上建置以啟動新執行個體或有選擇地啟動執行個體)。已經啟動的執行個體。 例如,也許您一次只希望一個執行個體編輯同一文檔,因此您將打開該文件的執行個體帶到前景,而不是啟動一個新執行個體。

這兩個範本都會新增 SupportsMultipleInstancespackage.appxmanifest 檔案。 請注意命名空間前綴 desktop4iot2:只有面向桌面的專案或物聯網 (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() 是執行的第一件事。 它會在 OnLaunchedOnActivated 之前執行。 這可讓您判斷在執行應用程式的任何其他初始化程序代碼之前,是否要啟動此執行個體或其他執行個體。

上述程式代碼會判斷應用程式的現有或新的執行個體是否已啟動。 金鑰可用來判斷是否有您想要啟動的現有執行個體。 例如,如果您的應用程式可以啟動以處理檔案啟用,您可以使用檔名作為金鑰。 然後,您可以檢查應用程式的執行個體是否已使用該金鑰註冊,並啟動它,而不是開啟新的執行個體。 這是程式碼背後的想法:var instance = AppInstance.FindOrRegisterInstanceForKey(key);

如果找到向金鑰註冊的執行個體,則會啟動該執行個體。 如果找不到索引鍵,則目前的執行個體 (目前正在執行的 Main 執行個體) 會建立其應用程式物件並開始執行。

背景工作和多重執行個體

  • 跨程式背景工作支援多重執行個體。 一般而言,每個新的觸發程序都會產生背景工作的新執行個體 (雖然從技術上講,多個背景工作可能會在相同的主機程序中執行)。 不過,會建立背景工作的不同執行個體。
  • 內部背景工作不支援多重執行個體。
  • 背景音訊工作不支援多重執行個體。
  • 當應用程式註冊背景工作時,它通常會先檢查該工作是否已註冊,然後刪除並重新註冊它,或不執行任何操作以保留現有註冊。 這仍然是多執行個體應用程式的一般行為。 不過,多執行個體應用程式可能會選擇在每個執行個體上註冊不同的背景工作名稱。 這會導致相同觸發程序的多個註冊,而且觸發程序引發時將會啟動多個背景工作執行個體。
  • App-services 會針對每個連線啟動個別的 App-Service 背景工作執行個體。 對於多執行個體應用程式來說,這保持不變,即多執行個體應用程式的每個執行個體都將獲得自己的應用程式服務背景工作執行個體。

其他考量

  • 以桌面和物聯網 (IoT) 專案為目標的 UWP 應用程式支援多重執行個體。
  • 為了避免競爭條件和爭用問題,多執行個體應用程式需要採取措施來分區/同步對設定、應用程式本地儲存以及任何其他資源 (例如使用者檔案、資料儲存等) 的存取,這些資源可以在多個執行個體之間共享。 可以使用標準同步處理機制,例如 Mutex、旗號、事件等等。
  • 如果應用程式在其 SupportsMultipleInstances Package.appxmanifest 檔案中有 ,則其延伸模組名不需要宣告 SupportsMultipleInstances
  • 如果新增 SupportsMultipleInstances 至背景工作或應用程式服務以外的任何其他延伸模組,且託管該延伸模組的應用程式也未在其 Package.appxmanifest 檔案中聲明 SupportsMultipleInstances,則會產生架構錯誤。
  • 應用程式可以使用其指令清單中的 ResourceGroup 宣告,將多個背景工作分組到相同的主機。 這與多執行個體衝突,在多執行個體中,每個啟動都進入一個單獨的主機。 因此,應用程式無法在其指令清單中宣告 SupportsMultipleInstancesResourceGroup

範例

如需多重執行個體啟用重新導向的範例,請參閱多重執行個體範例

另請參閱

AppInstance.FindOrRegisterInstanceForKeyAppInstance.GetActivatedEventArgsAppInstance.RedirectActivationTo處理應用程式啟用