Condividi tramite


Creare un'app di Windows universal a più istanze

Questo argomento descrive come creare app piattaforma Universal Windows multi-Instanca UWP (Universal Windows Platform).

Da Windows 10 versione 1803 (10.0; Build 17134) e versioni successive, l'app UWP può acconsentire esplicitamente al supporto di più istanze. Se è in esecuzione un'istanza di un'app UWP a più istanze e arriva una richiesta di attivazione successiva, la piattaforma non attiva l'istanza esistente. Al contrario, crea una nuova istanza che viene eseguita in un processo separato.

Importante

La creazione di più istanze è supportata per le applicazioni JavaScript, ma il reindirizzamento a più istanze non lo è. Poiché il reindirizzamento a più istanze non è supportato per le applicazioni JavaScript, la classe AppInstance non è utile per tali applicazioni.

Acconsentire esplicitamente al comportamento a istanze multiple

Se si sta creando una nuova applicazione a istanze multipla, è possibile installare modelli di progetto app a istanze multiple.VSIX, disponibili in Visual Studio Marketplace. Dopo aver installato i modelli, saranno disponibili nella finestra di dialogo Nuovo progetto in Visual C# > Windows universal (o Altre lingue > Visual C++ > Windows Universale).

Nota

Il modello Progetto app a istanze multipla non è più disponibile. Il modello VSIX è stato utile, quindi sarà necessario modificare il progetto esistente, come descritto di seguito. Assicurarsi di aggiungere la costante DISABLE_XAML_GENERATED_MAIN ai simboli di compilazione del progetto, in quanto impedisce alla compilazione di generare un main(). Ciò consente l'uso di una versione specifica dell'app appositamente scritta di Main().

Vengono installati due modelli: app UWP multiistanza, che fornisce il modello per la creazione di un'app a istanza multipla e app UWP di reindirizzamento a istanze multipla, che fornisce logica aggiuntiva su cui è possibile eseguire l'avvio di una nuova istanza o attivare in modo selettivo un'istanza già avviata. Ad esempio, magari, si vuole solo un'istanza alla volta modificando lo stesso documento, in modo da portare l'istanza con tale file aperto in primo piano anziché avviare una nuova istanza.

Entrambi i modelli aggiungono SupportsMultipleInstances al package.appxmanifest file. Si noti il prefisso dello spazio dei nomi desktop4 e iot2: solo i progetti destinati ai progetti desktop o Internet delle cose (IoT), supportano la creazione di istanza multipla.

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

Reindirizzamento dell'attivazione a istanza multipla

Il supporto a istanza multipla per le app UWP va oltre semplicemente rendendo possibile l'avvio di più istanze dell'app. Consente la personalizzazione nei casi in cui si vuole selezionare se viene avviata una nuova istanza dell'app o un'istanza già in esecuzione. Ad esempio, se l'app viene avviata per modificare un file già modificato in un'altra istanza, è possibile reindirizzare l'attivazione a tale istanza anziché aprire un'altra istanza che sta già modificando il file.

Per vederlo in azione, guardare questo video sulla creazione di app UWP a istanza multipla.

Il modello di app UWP reindirizzamento a istanze multiple aggiunge SupportsMultipleInstances al file package.appxmanifest come illustrato in precedenza e aggiunge anche un Program.cs (o Program.cpp, se si usa la versione C++ del modello) al progetto che contiene una funzione Main(). La logica per il reindirizzamento dell'attivazione viene inserita nella funzione Main. Di seguito è riportato il modello per Program.cs.

La proprietà AppInstance.RecommendedInstance rappresenta l'istanza preferita fornita dalla shell per questa richiesta di attivazione, se presente (o null se non ne esiste una). Se la shell fornisce una preferenza, è possibile reindirizzare l'attivazione a tale istanza oppure ignorarla se si sceglie.

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() è la prima cosa che viene eseguita. Viene eseguito prima di OnLaunched e OnActivated. Ciò consente di determinare se attivare questa o un'altra istanza prima dell'esecuzione di qualsiasi altro codice di inizializzazione nell'app.

Il codice precedente determina se viene attivata un'istanza esistente o nuova dell'applicazione. Viene usata una chiave per determinare se è presente un'istanza esistente che si desidera attivare. Ad esempio, se l'app può essere avviata per gestire l'attivazione dei file, è possibile usare il nome del file come chiave. È quindi possibile verificare se un'istanza dell'app è già registrata con tale chiave e attivarla invece di aprire una nuova istanza. Questa è l'idea dietro al codice: var instance = AppInstance.FindOrRegisterInstanceForKey(key);

Se viene trovata un'istanza registrata con la chiave, tale istanza viene attivata. Se la chiave non viene trovata, l'istanza corrente (l'istanza attualmente in esecuzione Main) crea il relativo oggetto applicazione e avvia l'esecuzione.

Attività in background e istanza multipla

  • Le attività in background out-of-process supportano la creazione di istanze multiple. In genere, ogni nuovo trigger genera una nuova istanza dell'attività in background (anche se tecnicamente più attività in background possono essere eseguite nello stesso processo host). Tuttavia, viene creata un'istanza diversa dell'attività in background.
  • Le attività in background in-process non supportano la creazione di istanze multiple.
  • Le attività audio in background non supportano la creazione di istanze multiple.
  • Quando un'app registra un'attività in background, in genere controlla prima di tutto se l'attività è già registrata e quindi la elimina e la registra nuovamente oppure non esegue alcuna operazione per mantenere la registrazione esistente. Questo è ancora il comportamento tipico con le app a istanze multiple. Tuttavia, un'app a istanza multipla può scegliere di registrare un nome di attività in background diverso per ogni istanza. Ciò comporterà più registrazioni per lo stesso trigger e più istanze di attività in background verranno attivate quando il trigger viene attivato.
  • I servizi app avviano un'istanza separata dell'attività in background del servizio app per ogni connessione. Ciò rimane invariato per le app a istanza multipla, ovvero ogni istanza di un'app a istanza multipla otterrà la propria istanza dell'attività in background del servizio app.

Considerazioni aggiuntive

  • L'istanza multipla è supportata dalle app UWP destinate a progetti desktop e Internet delle cose (IoT).
  • Per evitare problemi di race condition e contesa, le app a istanza multipla devono eseguire passaggi per partizionare/sincronizzare l'accesso alle impostazioni, all'archiviazione locale dell'app e a qualsiasi altra risorsa (ad esempio file utente, un archivio dati e così via) che possono essere condivisi tra più istanze. Sono disponibili meccanismi di sincronizzazione standard, ad esempio mutex, semafori, eventi e così via.
  • Se l'app ha SupportsMultipleInstances nel file Package.appxmanifest, le estensioni non devono dichiarare SupportsMultipleInstances.
  • Se si aggiunge SupportsMultipleInstances a qualsiasi altra estensione, a parte le attività in background o i servizi app e l'app che ospita l'estensione non dichiara SupportsMultipleInstances anche nel file Package.appxmanifest, viene generato un errore di schema.
  • Le app possono usare la dichiarazione ResourceGroup nel manifesto per raggruppare più attività in background nello stesso host. Questo è in conflitto con l'istanza multipla, in cui ogni attivazione viene inserita in un host separato. Pertanto, un'app non può dichiarare sia SupportsMultipleInstances che ResourceGroup nel manifesto.

Esempio

Per un esempio di reindirizzamento dell'attivazione a istanza multipla, vedere Esempio di istanza multipla.

Vedi anche

AppInstance.FindOrRegisterInstanceForKeyAppInstance.GetActivatedEventArgsAppInstance.RedirectActivationToGestire l'attivazione dell'app