Créer une application Windows universelle multi-instances
Cette rubrique explique comment créer des applications plateforme Windows universelle (UWP) multi-instances.
À partir de Windows 10, version 1803 (10.0 ; Build 17134) et versions ultérieures, votre application UWP peut être inscrite pour prendre en charge plusieurs instances. Si une instance d’une application UWP à instances multiples est en cours d’exécution et si une demande d’activation consécutive est reçue, la plateforme n’active pas l’instance existante. Au lieu de cela, elle crée une instance qui s’exécute dans un processus distinct.
Important
La multi-instanciation est prise en charge pour les applications JavaScript, mais pas la redirection multi-instanciation. Étant donné que la redirection multi-instanciation n’est pas prise en charge pour les applications JavaScript, la classe AppInstance n’est pas utile pour ces applications.
S'inscrire pour le comportement multi-instances
Si vous créez une application multi-instances, vous pouvez installer les Multi-Instance App Project Templates.VSIX, disponibles dans Visual Studio Marketplace. Une fois que vous avez installé les modèles, ils seront disponibles dans la boîte de dialogue Nouveau projet sous Visual C# > Windows Universel (ou Autres langages > Visual C++ > Windows Universel).
Remarque
Le modèle projet d’application multi-instances n’est plus disponible. Le modèle VSIX était pratique. Vous devrez donc modifier le projet existant, comme décrit ci-dessous. Veillez à ajouter la constante DISABLE_XAML_GENERATED_MAIN aux symboles de build du projet, car cela empêche la génération d’un Main() par défaut. Cela permet d’utiliser une version spécifique à l’application et spécialement écrite de Main().
Deux modèles sont installés : Multi-Instance UWP app, qui fournit le modèle de création d’une application multi-instances et Multi-Instance Redirection UWP app, qui fournit une logique supplémentaire sur laquelle vous pouvez vous appuyer pour lancer une nouvelle instance ou activer sélectivement une instance qui a déjà été lancée. Par exemple, vous ne souhaitez peut-être qu’une seule instance à la fois en modifiant le même document, de sorte que vous amenez au premier plan l’instance qui a ce fichier ouvert plutôt que de lancer une nouvelle instance.
Les deux modèles ajoutent SupportsMultipleInstances
au fichier package.appxmanifest
. Notez le préfixe d’espace de noms desktop4
et iot2
: seuls les projets qui ciblent le bureau ou les projets IoT (Internet des objets), prennent en charge la multi-instanciation.
<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>
Redirection de l’activation multi-instances
La prise en charge de la multi-instanciation pour les applications UWP va au-delà de la simple possibilité de lancer plusieurs instances de l’application. Cela permet la personnalisation dans les cas où vous souhaitez déterminer si une nouvelle instance de votre application est lancée ou si une instance déjà en cours d’exécution est activée. Par exemple, si l’application est lancée pour modifier un fichier déjà modifié dans une autre instance, vous pouvez rediriger l’activation vers cette instance au lieu d’ouvrir une autre instance qui est déjà en train de modifier le fichier.
Pour le voir en action, regardez cette vidéo sur la création d’applications UWP multi-instances.
Le modèle Multi-Instance Redirection UWP app ajoute SupportsMultipleInstances
au fichier package.appxmanifest, comme indiqué ci-dessus, et ajoute également un Program.cs (ou Program.cpp, si vous utilisez la version C++ du modèle) à votre projet qui contient une fonction Main()
. La logique de redirection de l’activation est incluse dans la fonction Main
. Le modèle de Program.cs est illustré ci-dessous.
La propriété AppInstance.RecommendedInstance représente l’instance préférée fournie par l’interpréteur de commandes pour cette demande d’activation, s’il en existe une (ou null
s’il n’en existe pas). Si l’interpréteur de commandes fournit une préférence, vous pouvez rediriger l’activation vers cette instance ou l’ignorer.
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()
est la première chose qui s’exécute. Il s’exécute avant OnLaunched et OnActivated. Cela vous permet de déterminer s’il faut activer cette instance ou une autre instance avant l’exécution d’un autre code d’initialisation dans votre application.
Le code ci-dessus détermine si une instance existante ou nouvelle de votre application est activée. Une clé est utilisée pour déterminer s’il existe une instance existante que vous souhaitez activer. Par exemple, si votre application peut être lancée pour gérer l’activation de fichiers, vous pouvez utiliser le nom de fichier comme clé. Vous pouvez ensuite vérifier si une instance de votre application est déjà inscrite avec cette clé et l’activer au lieu d’ouvrir une nouvelle instance. C'est l'idée principale du code : var instance = AppInstance.FindOrRegisterInstanceForKey(key);
Si une instance inscrite avec la clé est trouvée, cette instance est activée. Si la clé est introuvable, l’instance actuelle (l’instance qui exécute actuellement Main
) crée son objet d’application et commence à s’exécuter.
Tâches en arrière-plan et multi-instanciation
- Les tâches en arrière-plan hors processus prennent en charge la multi-instanciation. En règle générale, chaque nouveau déclencheur entraîne une nouvelle instance de la tâche en arrière-plan (bien que techniquement, plusieurs tâches en arrière-plan puissent s’exécuter dans le même processus hôte). Néanmoins, une autre instance de la tâche en arrière-plan est créée.
- Les tâches en arrière-plan en cours ne prennent pas en charge la multi-instanciation.
- Les tâches audio en arrière-plan ne prennent pas en charge la multi-instanciation.
- Lorsqu’une application inscrit une tâche en arrière-plan, elle vérifie généralement si la tâche est déjà inscrite, puis supprime et réinscrit celle-ci, ou ne fait rien pour conserver l’inscription existante. C'est ainsi que fonctionnent généralement les applications multi-instances. Toutefois, une application multi-instanciation peut choisir d’inscrire un nom de tâche en arrière-plan différent par instance. Cela entraîne l’activation de plusieurs inscriptions pour le même déclencheur, et plusieurs instances de tâche en arrière-plan sont activées lorsque le déclencheur se déclenche.
- Les services d’application lancent une instance distincte de leur tâche en arrière-plan pour chaque connexion. Cela reste inchangé pour les applications multi-instances, c’est-à-dire que chaque instance d’une application multi-instance obtient sa propre instance de la tâche en arrière-plan du service d'application.
Considérations supplémentaires
- La multi-instanciation est prise en charge par les applications UWP qui ciblent les projets Bureau et IoT (Internet des objets).
- Pour éviter les problèmes de concurrence et de contention, les applications multi-instances doivent prendre des mesures pour partitionner/synchroniser l’accès aux paramètres, au stockage local d’application et à toute autre ressource (comme les fichiers utilisateur, un magasin de données, etc.) qui peuvent être partagés entre plusieurs instances. Les mécanismes de synchronisation standard tels que les mutex, les sémaphores, les événements, etc. sont disponibles.
- Si l’application a
SupportsMultipleInstances
dans son fichier Package.appxmanifest, ses extensions n’ont pas besoin de déclarerSupportsMultipleInstances
. - Si vous ajoutez
SupportsMultipleInstances
à une autre extension, en dehors des tâches en arrière-plan ou des services d’application, et que l’application qui héberge l’extension ne déclare pas aussiSupportsMultipleInstances
dans son fichier Package.appxmanifest, une erreur de schéma est générée. - Les applications peuvent utiliser la déclaration ResourceGroup dans leur manifeste pour regrouper plusieurs tâches en arrière-plan dans le même hôte. Cela est en conflit avec la multi-instanciation, où chaque activation passe dans un hôte distinct. Par conséquent, une application ne peut pas déclarer à la fois
SupportsMultipleInstances
etResourceGroup
dans son manifeste.
Exemple
Consultez l’exemple multi-instance illustrant un cas de redirection d’activation multi-instances.
Voir aussi
AppInstance.FindOrRegisterInstanceForKeyAppInstance.GetActivatedEventArgsAppInstance.RedirectActivationToHandle app activation