次の方法で共有


複数インスタンスのユニバーサル Windows アプリを作成する

このトピックでは、複数インスタンスのユニバーサル Windows プラットフォーム (UWP) アプリを作成する方法について説明します。

Windows 10 バージョン 1803 (10.0;ビルド 17134) 以降では、UWP アプリで複数のインスタンスをサポートするようにオプトインできます。 マルチインスタンス UWP アプリのインスタンスが実行されていて、後続のアクティブ化要求が送信された場合、プラットフォームは既存のインスタンスをアクティブ化しません。 代わりに、別のプロセスで実行される新しいインスタンスが作成されます。

複数インスタンスの動作にオプトインする

新しいマルチインスタンス アプリケーションを作成する場合は、Visual Studio Marketplaceから入手できる Multi-Instance App Project Templates.VSIXをインストールできます。 テンプレートをインストールすると、Visual C# Windows ユニバーサル (または Visual C++ Windows ユニバーサル その他の言語を ) の下にある [新しいプロジェクト] ダイアログで使用できるようになります。

マルチインスタンス アプリ プロジェクト テンプレートは使用できなくなりました。 VSIX テンプレートは便利なので、次に説明するように、代わりに既存のプロジェクトを変更する必要があります。 ビルドで既定の Main() が生成されないようにするため、プロジェクトビルドシンボルにDISABLE_XAML_GENERATED_MAIN定数を追加してください。 これにより、特別に記述されたアプリ固有バージョンの Main() を使用できます。

2 つのテンプレートがインストールされています。マルチインスタンス UWP アプリ(マルチインスタンス アプリを作成するためのテンプレートを提供します)、マルチインスタンス リダイレクト UWP アプリ。これは、新しいインスタンスを起動するか、既に起動されているインスタンスを選択的にアクティブ化するために構築できる追加のロジックを提供します。 たとえば、同じドキュメントを一度に編集するインスタンスが 1 つだけ必要な場合は、新しいインスタンスを起動するのではなく、そのファイルをフォアグラウンドに開いたインスタンスを表示します。

どちらのテンプレートも、SupportsMultipleInstances ファイルに package.appxmanifest を追加します。 名前空間プレフィックス desktop4注意してください。デスクトップを対象とするプロジェクトのみがマルチインスタンス化をサポートします。

アプリが Windows 10 バージョン 2004 (ビルド 19041) 以降を対象とする場合は、uap10:SupportsMultipleInstancesではなく、新しいdesktop4:SupportsMultipleInstances属性を使用できます。 uap10名前空間は、新しいアプリケーションに推奨される方法です。

<Package
  ...
  xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
  IgnorableNamespaces="uap mp desktop4">
  ...
  <Applications>
    <Application Id="App"
      ...
      desktop4:SupportsMultipleInstances="true">
      ...
    </Application>
  </Applications>
   ...
</Package>

複数インスタンスアクティベーションのリダイレクト

UWP アプリのマルチインスタンス化のサポートは、単にアプリの複数のインスタンスを起動することを可能にするだけでなく、 これにより、アプリの新しいインスタンスを起動するか、既に実行されているインスタンスをアクティブにするかを選択する場合にカスタマイズできます。 たとえば、別のインスタンスで既に編集されているファイルを編集するためにアプリが起動された場合、既にファイルを編集している別のインスタンスを開くのではなく、そのインスタンスにアクティブ化をリダイレクトすることができます。

動作を確認するには、マルチインスタンス UWP アプリの作成に関するこのビデオをご覧ください。

マルチインスタンス リダイレクト UWP アプリ テンプレートは、上記のように package.appxmanifest ファイルに SupportsMultipleInstances を追加し、 関数を含むプロジェクトに Program.cs (またはテンプレートの 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 バックグラウンド タスクの個別のインスタンスを起動します。 これは、マルチインスタンス アプリでは変更されません。マルチインスタンス アプリの各インスタンスは、App-Service バックグラウンド タスクの独自のインスタンスを取得します。

その他の考慮事項

  • マルチインスタンス化は、デスクトップ プロジェクトを対象とする UWP アプリでサポートされています。
  • 競合状態や競合の問題を回避するには、マルチインスタンス アプリは、設定、アプリローカル ストレージ、および複数のインスタンス間で共有できるその他のリソース (ユーザー ファイル、データ ストアなど) へのアクセスをパーティション分割/同期する手順を実行する必要があります。 ミューテックス、セマフォ、イベントなどの標準的な同期メカニズムを使用できます。
  • アプリが Package.appxmanifest ファイルに SupportsMultipleInstances している場合、その拡張子は SupportsMultipleInstances宣言する必要はありません。
  • バックグラウンド タスクや app-services 以外の他の拡張機能に SupportsMultipleInstances を追加した場合、拡張機能をホストするアプリも Package.appxmanifest ファイルで SupportsMultipleInstances を宣言しないと、スキーマ エラーが生成されます。
  • アプリでは、マニフェストで ResourceGroup 宣言を使用して、複数のバックグラウンド タスクを同じホストにグループ化できます。 これはマルチインスタンス化と競合し、各アクティブ化は個別のホストに入ります。 そのため、アプリはマニフェストで SupportsMultipleInstancesResourceGroup の両方を宣言できません。

サンプル

マルチインスタンスアクティベーションリダイレクトの例については、サンプル マルチインスタンス を参照してください。

こちらも参照ください

AppInstance.FindOrRegisterInstanceForKeyAppInstance.GetActivatedEventArgsAppInstance.RedirectActivationToアプリのアクティブ化 を処理する