Dela via


Skapa en universell Windows-app för flera instanser

Det här avsnittet beskriver hur du skapar UWP-appar (Universal Windows Platform) för flera instanser.

Från Windows 10 version 1803 (10.0; Skapa 17134) och framåt kan UWP-appen välja att stödja flera instanser. Om en instans av en UWP-app med flera instanser körs och en efterföljande aktiveringsbegäran kommer igenom aktiverar plattformen inte den befintliga instansen. I stället skapas en ny instans som körs i en separat process.

Aktivera funktionen för flera instanser

Om du skapar ett nytt program med flera instanser kan du installera Multi-Instance App Project Templates.VSIX, som är tillgängligt från Visual Studio Marketplace. När du har installerat mallarna blir de tillgängliga i dialogrutan New Project under Visual C# > Windows Universal (eller Andra språk > Visual C++ > Windows Universal).

Notera

Mallen Multi-Instance App Project är inte längre tillgänglig. VSIX-mallen var en bekvämlighet, så du måste ändra det befintliga projektet i stället, enligt beskrivningen nedan. Var säker på att lägga till den DISABLE_XAML_GENERATED_MAIN konstanten i projektversionssymbolerna, eftersom det förhindrar att bygget genererar en standard main(). Detta tillåter användning av en särskilt skriven appspecifik version av Main().

Två mallar är installerade: UWP-app för flera instanser, som tillhandahåller mallen för att skapa en app med flera instanser och UWP-app för multiinstansomdirigering, vilket ger ytterligare logik som du kan bygga vidare på för att antingen starta en ny instans eller selektivt aktivera en instans som redan har startats. Du kanske till exempel bara vill ha en instans i taget som redigerar samma dokument, så att du öppnar den instans som har filen i förgrunden i stället för att starta en ny instans.

Båda mallarna lägger till SupportsMultipleInstances i package.appxmanifest-filen. Observera namnområdesprefixet desktop4: endast projekt som riktar sig mot skrivbordet stöder multi-instancing.

Notera

Om din app är avsedd för Windows 10, version 2004 (build 19041) eller senare kan du använda det nyare uap10:SupportsMultipleInstances attributet i stället för desktop4:SupportsMultipleInstances. Namnområdet uap10 är den föredragna metoden för nyare program.

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

Omdirigering av aktivering med flera instanser

Stöd för flerfaldig instansiering av UWP-appar går längre än att bara göra det möjligt att starta flera instanser av appen. Det möjliggör anpassning i fall där du vill välja om en ny instans av din app startas eller om en instans som redan körs är aktiverad. Om appen till exempel startas för att redigera en fil som redan redigeras i en annan instans kanske du vill omdirigera aktiveringen till den instansen i stället för att öppna en annan instans som redan redigerar filen.

Om du vill se den i praktiken kan du titta på den här videon om att skapa UWP-appar med flera instanser.

UWP-mallen för flera instanser lägger tillSupportsMultipleInstances i filen package.appxmanifest, som visas ovan, och lägger också till en Program.cs (eller Program.cpp, om du använder C++-versionen av mallen) till ditt projekt som innehåller en Main() funktion. Logiken för omdirigering av aktivering finns i funktionen Main. Mallen för Program.cs visas nedan.

Egenskapen AppInstance.RecommendedInstance representerar den gränssnittsspecifika föredragna instansen för den här aktiveringsbegäran, om det finns en (eller null om det inte finns någon). Om gränssnittet har en inställning kan du omdirigera aktiveringen till den instansen, eller så kan du ignorera den om du väljer det.

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() är det första som körs. Detta körs innan OnLaunched och OnActivated. På så sätt kan du avgöra om du vill aktivera den här eller en annan instans innan någon annan initieringskod i appen körs.

Koden ovan avgör om en befintlig eller ny instans av ditt program är aktiverad. En nyckel används för att avgöra om det finns en befintlig instans som du vill aktivera. Om din app till exempel kan startas för att Hantera filaktiveringkan du använda filnamnet som en nyckel. Sedan kan du kontrollera om en instans av din app redan är registrerad med den nyckeln och aktivera den i stället för att öppna en ny instans. Det här är tanken bakom koden: var instance = AppInstance.FindOrRegisterInstanceForKey(key);

Om en instans som är registrerad med nyckeln hittas aktiveras den instansen. Om nyckeln inte hittas skapar den aktuella instansen (den instans som för närvarande kör Main) sitt programobjekt och börjar köras.

Bakgrundsaktiviteter och flera instanser

  • Bakgrundsuppgifter utanför processen stöder flera instanser. Vanligtvis resulterar varje ny utlösare i en ny instans av bakgrundsaktiviteten (även om flera bakgrundsaktiviteter tekniskt sett kan köras i samma värdprocess). Trots detta skapas en annan instans av bakgrundsaktiviteten.
  • Bakgrundsaktiviteter i processen stöder inte multi-instancing.
  • Bakgrundsljuduppgifter stöder inte multi-instancing.
  • När en app registrerar en bakgrundsaktivitet kontrollerar den vanligtvis först om aktiviteten redan är registrerad och sedan antingen tar bort och registrerar den igen, eller gör ingenting för att behålla den befintliga registreringen. Detta är fortfarande det typiska beteendet med appar med flera instanser. En app med flera instanser kan dock välja att registrera ett annat bakgrundsuppgiftsnamn per instans. Detta resulterar i flera registreringar för samma utlösare och flera instanser av bakgrundsaktiviteter aktiveras när utlösaren utlöses.
  • App-services startar en separat instans av apptjänstens bakgrundsaktivitet för varje anslutning. Detta förblir oförändrat för appar med flera instanser, vilket är att varje instans av en app med flera instanser får en egen instans av apptjänstens bakgrundsaktivitet.

Ytterligare överväganden

  • Multi-instancing stöds av UWP-appar som riktar sig till skrivbordsprojekt.
  • För att undvika konkurrensproblem måste appar med flera instanser vidta åtgärder för att partitioneras/synkronisera åtkomst till inställningar, applokal lagring och andra resurser (till exempel användarfiler, ett datalager och så vidare) som kan delas mellan flera instanser. Standardsynkroniseringsmekanismer som mutex, semaphores, händelser och så vidare är tillgängliga.
  • Om appen har SupportsMultipleInstances i filen Package.appxmanifest behöver dess tillägg inte deklarera SupportsMultipleInstances.
  • Om du lägger till SupportsMultipleInstances till något annat tillägg, förutom bakgrundsaktiviteter eller apptjänster, och appen som är värd för tillägget inte också deklarerar SupportsMultipleInstances i filen Package.appxmanifest, genereras ett schemafel.
  • Appar kan använda deklarationen ResourceGroup i manifestet för att gruppera flera bakgrundsuppgifter i samma värd. Detta står i konflikt med att använda flera instanser, där varje aktivering hamnar i en separat värd. Därför kan inte en app deklarera både SupportsMultipleInstances och ResourceGroup i manifestet.

Exempel

Se Multi-Instance-exempel för ett exempel på omdirigering av aktiveringar för flera instanser.

Se även

AppInstance.FindOrRegisterInstanceForKeyAppInstance.GetActivatedEventArgsAppInstance.RedirectActivationToHantera app-aktivering