Erstellen einer universellen Windows-App mit mehreren Instanzen

In diesem Thema wird beschrieben, wie Sie Universal Windows-Plattform-(UWP-)Apps mit mehreren Instanzen erstellen.

Ab Windows 10, Version 1803 (10.0; Build 17134) und höher kann Ihre UWP-App mehrere Instanzen unterstützen. Wenn eine Instanz einer UWP-App mit mehreren Instanzen ausgeführt wird und eine nachfolgende Aktivierungsanforderung eingeht, wird die vorhandene Instanz von der Plattform nicht aktiviert. Stattdessen wird eine neue Instanz erstellt, die in einem separaten Prozess ausgeführt wird.

Wichtig

Multi-Instancing wird für JavaScript-Anwendungen unterstützt, jedoch nicht die Umleitung für mehrere Instanzen. Da die Umleitung für mehrere Instanzen für JavaScript-Anwendungen nicht unterstützt wird, ist die AppInstance-Klasse für solche Anwendungen nicht nützlich.

Anmelden für das Verhalten mit mehreren Instanzen

Wenn Sie eine neue Anwendung mit mehreren Instanzen erstellen, können Sie die Project Templates.VSIX mit mehreren Instanzen installieren, die im Visual Studio Marketplace verfügbar ist. Nachdem Sie die Vorlagen installiert haben, sind sie im Dialogfeld Neues Projekt unter Visual C# > Windows Universal (oder Sonstige Sprachen > Visual C++ > Windows Universal) verfügbar.

Hinweis

Die Projektvorlage „App mit mehreren Instanzen“ ist nicht mehr verfügbar. Die VSIX-Vorlage war eine Behelfsvorlage, daher müssen Sie stattdessen das vorhandene Projekt ändern, wie unten beschrieben. Achten Sie darauf, die den Projektbuildsymbolen DISABLE_XAML_GENERATED_MAIN-Konstante hinzuzufügen, da so verhindert wird, dass der Build ein Standard-Main() generiert. Dies ermöglicht die Verwendung einer speziell geschriebenen app-spezifischen Version von Main().

Zwei Vorlagen werden installiert: UWP-App mit mehreren Instanzen, die die Vorlage zum Erstellen einer entsprechenden App bereitstellt, und UWP-Umleitungs-App mit mehreren Instanzen, die zusätzliche Logik bereitstellt, auf der Sie entweder eine neue Instanz starten oder eine bereits gestartete Instanz selektiv aktivieren können. Beispielsweise möchten Sie nur eine Instanz gleichzeitig mit demselben Dokument bearbeiten, sodass Sie die Instanz mit geöffneter Datei im Vordergrund verwenden, anstatt eine neue Instanz zu starten.

Beide Vorlagen werden der SupportsMultipleInstances Datei package.appxmanifest hinzugefügt. Beachten Sie das Namespacepräfix desktop4 und iot2: nur Projekte, die auf Desktop- oder Internet of Things-(IoT-)Projekte abzielen, unterstützen die Erstellung mit mehreren Instanzen.

<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>

Umleitung der Aktivierung mit mehreren Instanzen

Der Support für mehrere Instanzen für UWP-Apps geht über die einfache Möglichkeit hinaus, mehrere Instanzen der App zu starten. Sie ermöglicht Anpassungen in Fällen, in denen Sie auswählen möchten, ob eine neue Instanz Ihrer App gestartet oder ob eine bereits ausgeführte Instanz aktiviert ist. Wenn die App beispielsweise gestartet wird, um eine Datei zu bearbeiten, die bereits in einer anderen Instanz bearbeitet wird, können Sie die Aktivierung an diese Instanz umleiten, anstatt eine andere Instanz zu öffnen, die die Datei bereits bearbeitet.

Sehen Sie sich den Vorgang in diesem Video zum Erstellen von UWP-Apps mit mehreren Instanzen an.

Die Vorlage UWP-Umleitungs-App mit mehreren Instanzen fügt der Datei SupportsMultipleInstances „package.appxmanifest“ wie oben gezeigt hinzu, sowie Program.cs (oder Program.cpp, wenn Sie die C++-Version der Vorlage verwenden) Ihrem Projekt, das eine Main()-Funktion enthält. Die Logik für die Umleitungsaktivierung fließt in die Main-Funktion. Die Vorlage für Program.cs wird unten angezeigt.

Die Eigenschaft AppInstance.RecommendedInstance stellt die von Shell bereitgestellte bevorzugte Instanz für diese Aktivierungsanforderung dar, sofern vorhanden (oder null wenn keine vorhanden ist). Wenn die Shell eine Einstellung bereitstellt, können Sie die Aktivierung an diese Instanz umleiten oder sie bei Auswahl ignorieren.

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() ist das erste, was ausgeführt wird. Es wird vor OnLaunched und OnActivated ausgeführt. Auf diese Weise können Sie ermitteln, ob dieses oder eine andere Instanz aktiviert werden soll, bevor ein anderer Initialisierungscode in Ihrer App ausgeführt wird.

Der obige Code bestimmt, ob eine vorhandene oder eine neue Instanz Ihrer Anwendung aktiviert ist. Ein Schlüssel wird verwendet, um zu bestimmen, ob eine vorhandene Instanz zum Aktivieren vorhanden ist. Wenn Ihre App beispielsweise zur Dateiaktivierung gestartet werden kann, können Sie den Dateinamen als Schlüssel verwenden. Anschließend können Sie überprüfen, ob eine Instanz Ihrer App bereits mit diesem Schlüssel registriert und aktiviert wird, anstatt eine neue Instanz zu öffnen. Dies ist die Überlegung hinter dem Code: var instance = AppInstance.FindOrRegisterInstanceForKey(key);

Wenn eine mit dem Schlüssel registrierte Instanz gefunden wird, wird sie aktiviert. Wenn der Schlüssel nicht gefunden wird, erstellt die aktuelle Instanz (die derzeit ausgeführte Instanz) Main das Anwendungsobjekt und startet die Ausführung.

Hintergrundaufgaben und Multi-Instancing

  • Out-of-Process-Hintergrundaufgaben unterstützen das Multi-Instancing. In der Regel führt jeder neue Trigger zu einer neuen Hintergrundaufgabeninstanz (obwohl technisch gesehen mehrere Hintergrundaufgaben im selben Hostprozess ausgeführt werden können). Dennoch wird eine andere Instanz der Hintergrundaufgabe erstellt.
  • In-Process-Hintergrundaufgaben unterstützen kein Multi-Instancing.
  • Hintergrundaudioaufgaben unterstützen kein Multi-Instancing.
  • Wenn eine App eine Hintergrundaufgabe registriert, überprüft sie in der Regel zuerst, ob die Aufgabe bereits registriert ist. Die Aufgabe wird dann entweder gelöscht oder erneut registriert, bzw. die vorhandene Registrierung wird beibehalten. Dies ist weiterhin das typische Verhalten bei Apps mit mehreren Instanzen. Eine Multi-Instancing-App kann sich jedoch entscheiden, einen anderen Hintergrundaufgabennamen pro Instanz zu registrieren. Dies führt zu mehreren Registrierungen für denselben Trigger, und mehrere Hintergrundaufgabeninstanzen werden aktiviert, wenn der Trigger ausgelöst wird.
  • App-Dienste starten eine separate Instanz der Hintergrundaufgabe des App-Diensts für jede Verbindung. Dies bleibt für Apps mit mehreren Instanzen unverändert, d. h. jede Instanz einer App mit mehreren Instanzen erhält eine eigene Instanz der App-Dienst-Hintergrundaufgabe.

Weitere Überlegungen

  • Multi-Instancing wird von UWP-Apps unterstützt, die auf Desktop- und Internet of Things-(IoT-)Projekte abzielen.
  • Um Racebedingungen und Konflikte zu vermeiden, müssen Apps mit mehreren Instanzen Schritte ausführen, um den Zugriff auf Einstellungen, den App-Speicher und alle anderen Ressourcen (z. B. Benutzerdateien, Datenspeicher usw.) zu partitionieren/synchronisieren, die für mehrere Instanzen freigegeben werden können. Standardsynchronisierungsmechanismen wie Mutexes, Semaphoren, Ereignisse usw. sind verfügbar.
  • Wenn die App SupportsMultipleInstances in ihrer Package.appxmanifest-Datei enthält, müssen die Erweiterungen nicht deklariert werden SupportsMultipleInstances.
  • Wenn Sie einer anderen Erweiterung abgesehen von Hintergrundaufgaben oder App-Diensten SupportsMultipleInstances hinzufügen , und die App, die die Erweiterung hostet, SupportsMultipleInstances auch nicht in der Package.appxmanifest-Datei deklariert, wird ein Schemafehler generiert.
  • Apps können die ResourceGroup-Deklaration in ihrem Manifest verwenden, um mehrere Hintergrundaufgaben auf demselben Host zu gruppieren. Dies steht in Konflikt mit Multi-Instancing, bei dem jede Aktivierung in einen separaten Host wechselt. Daher kann eine App nicht sowohl SupportsMultipleInstances als auch ResourceGroup in ihrem Manifest deklarieren.

Beispiel

Ein Beispiel für die Umleitung der Aktivierung mit mehreren Instanzen finden Sie unter Beispiel für mehrere Instanzen.

Weitere Informationen

AppInstance.FindOrRegisterInstanceForKeyAppInstance.GetActivatedEventArgsAppInstance.RedirectActivationToApp-Aktivierung