Share via


Een universele Windows-app met meerdere exemplaren maken

In dit onderwerp wordt beschreven hoe u UWP-apps (Universal Windows Platform) met meerdere exemplaren maakt.

Vanaf Windows 10 versie 1803 (10.0; Vanaf build 17134 kan uw UWP-app ervoor kiezen om meerdere exemplaren te ondersteunen. Als een exemplaar van een UWP-app met meerdere exemplaren wordt uitgevoerd en er een volgende activeringsaanvraag wordt ingediend, activeert het platform het bestaande exemplaar niet. In plaats daarvan wordt er een nieuw exemplaar gemaakt dat in een afzonderlijk proces wordt uitgevoerd.

Belangrijk

Multi-instancing wordt ondersteund voor JavaScript-toepassingen, maar omleiding met meerdere instancings is dat niet. Omdat multi-instancing-omleiding niet wordt ondersteund voor JavaScript-toepassingen, is de AppInstance-klasse niet nuttig voor dergelijke toepassingen.

Kiezen voor multi-instantiegedrag

Als u een nieuwe toepassing met meerdere exemplaren maakt, kunt u de Multi-Instance App Project Templates.VSIXinstalleren, verkrijgbaar in de Visual Studio Marketplace. Nadat u de sjablonen hebt geïnstalleerd, zijn deze beschikbaar in het dialoogvenster Nieuw project onder Visual C# > Universele Windows- (of Andere talen > Visual C++ > Universele Windows-).

Notitie

Het sjabloon voor de Multi-Instance App Project is niet meer beschikbaar. De VSIX-sjabloon was handig, dus u moet in plaats daarvan het bestaande project wijzigen, zoals hieronder wordt beschreven. Zorg ervoor dat u de DISABLE_XAML_GENERATED_MAIN constante toevoegt aan de buildsymbolen van het project, omdat hiermee wordt voorkomen dat de build een standaard main() genereert. Hiermee kunt u een speciaal geschreven app-specifieke versie van Main() gebruiken.

Er zijn twee sjablonen geïnstalleerd: UWP-app met meerdere exemplaren, die de sjabloon biedt voor het maken van een app met meerdere exemplaren en UWP-app voor omleiding van meerdere exemplaren, die aanvullende logica biedt waarmee u een nieuw exemplaar kunt starten of selectief een exemplaar kunt activeren dat al is gestart. Misschien wilt u bijvoorbeeld slechts één instantie tegelijk hetzelfde document bewerken, zodat u de instantie met dat bestand naar de voorgrond haalt in plaats van een nieuwe instantie te starten.

Beide sjablonen voegen SupportsMultipleInstances toe aan het package.appxmanifest-bestand. Let op het voorvoegsel van de naamruimte desktop4 en iot2: alleen projecten die gericht zijn op het bureaublad of het Internet der Dingen (IoT) ondersteunen multi-instancing.

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

Omleiding voor activering van meerdere instanties

Ondersteuning voor meerdere instanties van UWP-apps gaat verder dan alleen het mogelijk maken om meerdere instanties van de app te starten. Het maakt aanpassing mogelijk in gevallen waarin u wilt selecteren of een nieuw exemplaar van uw app wordt gestart of een exemplaar dat al wordt uitgevoerd, is geactiveerd. Als de app bijvoorbeeld wordt gestart om een bestand te bewerken dat al in een ander exemplaar wordt bewerkt, kunt u de activering omleiden naar dat exemplaar in plaats van een ander exemplaar te openen dat het bestand al bewerkt.

Kijk deze video over het maken van multi-instance UWP-apps om te zien hoe het werkt.

De UWP-app voor omleiding met meerdere exemplaren sjabloon voegt SupportsMultipleInstances toe aan het bestand package.appxmanifest zoals hierboven wordt weergegeven en voegt ook een Program.cs (of Program.cpp, als u de C++-versie van de sjabloon gebruikt) toe aan uw project met een Main() functie. De logica voor het omleiden van activering gaat in de functie Main. De sjabloon voor Program.cs wordt hieronder weergegeven.

De eigenschap AppInstance.RecommendedInstance vertegenwoordigt het door de shell geleverde voorkeursexemplaren voor deze activeringsaanvraag, als er een is (of null als er geen is). Als de shell een voorkeur biedt, kunt u de activering omleiden naar dat exemplaar, of u kunt deze negeren als u dat kiest.

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() is het eerste dat uitgevoerd wordt. Het wordt uitgevoerd voordat OnLaunched en OnActivated. Hiermee kunt u bepalen of u deze of een ander exemplaar moet activeren voordat andere initialisatiecode in uw app wordt uitgevoerd.

De bovenstaande code bepaalt of een bestaand of nieuw exemplaar van uw toepassing is geactiveerd. Er wordt een sleutel gebruikt om te bepalen of er een bestaand exemplaar is dat u wilt activeren. Als uw app bijvoorbeeld kan worden gestart om te bestandsactiveringverwerken, kunt u de bestandsnaam als sleutel gebruiken. Vervolgens kunt u controleren of een exemplaar van uw app al is geregistreerd bij die sleutel en deze activeert in plaats van een nieuw exemplaar te openen. Dit is het idee achter de code: var instance = AppInstance.FindOrRegisterInstanceForKey(key);

Als er een exemplaar wordt gevonden dat met de sleutel is geregistreerd, wordt dat exemplaar geactiveerd. Als de sleutel niet wordt gevonden, creëert het huidige exemplaar (het exemplaar dat momenteel wordt uitgevoerd Main) zijn toepassingsobject en begint te draaien.

Achtergrondtaken en multi-instancing

  • Achtergrondtaken die buiten het proces draaien ondersteunen multi-instancing. Normaal gesproken resulteert elke nieuwe trigger in een nieuw exemplaar van de achtergrondtaak (hoewel technisch gesproken meerdere achtergrondtaken in hetzelfde hostproces kunnen worden uitgevoerd). Toch wordt een ander exemplaar van de achtergrondtaak gemaakt.
  • In-proc-achtergrondtaken bieden geen ondersteuning voor multi-instancing.
  • Achtergrondaudiotaken bieden geen ondersteuning voor multi-instancing.
  • Wanneer een app een achtergrondtaak registreert, wordt meestal eerst gecontroleerd of de taak al is geregistreerd en vervolgens wordt de taak verwijderd en opnieuw geregistreerd, of wordt er niets gedaan om de bestaande registratie te behouden. Dit is nog steeds het typische gedrag van apps met meerdere instanties. Een app voor meerdere instellingen kan er echter voor kiezen om per instantie een andere achtergrondtaaknaam te registreren. Dit resulteert in meerdere registraties voor dezelfde trigger en er worden meerdere instanties van achtergrondtaken geactiveerd wanneer de trigger wordt geactiveerd.
  • App-services starten een afzonderlijk exemplaar van de app-service-achtergrondtaak voor elke verbinding. Dit blijft ongewijzigd voor apps met meerdere exemplaren, dat wil zeggen dat elk exemplaar van een app met meerdere exemplaren een eigen exemplaar van de app-service-achtergrondtaak krijgt.

Aanvullende overwegingen

  • Multi-instancing wordt ondersteund door UWP-apps die gericht zijn op IoT-projecten (desktop en Internet of Things).
  • Om racevoorwaarden en conflicten te voorkomen, moeten apps met meerdere exemplaren stappen uitvoeren om de toegang tot instellingen, app-lokale opslag en andere resources (zoals gebruikersbestanden, een gegevensarchief, enzovoort) te partitioneren/synchroniseren, die kunnen worden gedeeld tussen meerdere exemplaren. Standaardsynchronisatiemechanismen, zoals mutexes, semaphores, gebeurtenissen, enzovoort, zijn beschikbaar.
  • Als de app SupportsMultipleInstances in het bestand Package.appxmanifest heeft, hoeven de extensies SupportsMultipleInstancesniet te declareren.
  • Als u SupportsMultipleInstances toevoegt aan een andere extensie, behalve achtergrondtaken of app-services, en de app die als host fungeert voor de extensie, declareert niet ook SupportsMultipleInstances in het bestand Package.appxmanifest, wordt er een schemafout gegenereerd.
  • Apps kunnen de declaratie ResourceGroup in hun manifest gebruiken om meerdere achtergrondtaken in dezelfde host te groeperen. Dit conflicteert met multi-instancing, waarbij elke activering naar een afzonderlijke host gaat. Een app kan daarom niet zowel SupportsMultipleInstances als ResourceGroup in hun manifest declareren.

Monster

Zie Multi-Instance voorbeeld voor een voorbeeld van herleiding van multi-instance activering.

Zie ook

AppInstance.FindOrRegisterInstanceForKeyAppInstance.GetActivatedEventArgsAppInstance.RedirectActivationToApp-activering afhandelen