#Windows10 : Association de protocole et d’extensions de fichier améliorés pour une meilleure communication inter-apps #B2B
Dans mon précédent article je vous ai parlé d’AppService qui va faciliter la communication inter-applications Windows 10 en permettant d’héberger une sorte de web-service dans une application. Cependant ce ne sont pas les seules évolutions dans ce domaine et je vais vous présenter les autres nouveautés dans cet article.
Que peut t-on faire sur Windows 8.1 ?
Il était déjà possible d’associer un protocole à une application. Ouvrir une url en utilisant ce protocole depuis une application Windows ou depuis l’explorateur permettait d’activer l’application associée en lui passant des arguments. Voici un exemple lançant Skype :
var uri = new Uri("skype://0671860000", UriKind.Absolute); Windows.System.Launcher.LaunchUriAsync(uri);
Cela est bien pratique mais présente quand même certaines limitations :
- Impossible de passer beaucoup de données.
- Impossible de donner l’accès à un fichier.
- L’utilisateur peut choisir n’importe quelle application pour ouvrir ce protocole et pas nécessairement la votre.
- Il est impossible de savoir si l’application a fini d’interpréter son activation.
- L’application cible ne peut rien renvoyer facilement en retour. Il fallait soit même implémenter un protocole pour que l’application cible nous “rappelle” (Facebook utilise ce système pour l’authentification par exemple).
De la même façon, il est possible d’associer une extension de fichier à une application. Le fonctionnement sera exactement le même que pour le protocole avec les mêmes limitations.
Les nouveautés de Windows 10
La volonté de Microsoft est d’enlever ces limitations en proposant ces APIs :
- Lancer une application bien spécifique par protocole en fournissant son nom de package
- Lancer une application bien spécifique (ou non) par protocole en fournissant un fichier
- Lancer une application bien spécifique (ou non) par protocole et attendre qu’elle nous retourne un objet
- Lancer une application bien spécifique (ou non) via extension de fichier
- Vérifier qu’une application gérant un protocole est bien installée sur le PC
Cela permet donc d’adresser les différentes limitations présentes dans le SDK Windows 8 et d’avoir des scénarios complets de communication inter-applications.
Dans le code cela donne ce genre de choses :
// Définition de variable d'aide var protocolUri = new Uri("InfiniteSquare://", UriKind.Absolute); var packageFamilyName = "MonIdDePackage"; var fileUri = new Uri("ms-appx:///NousAInfiniteSquare.file"); var file = await StorageFile.GetFileFromApplicationUriAsync(fileUri); var folder = ApplicationData.Current.LocalFolder; LauncherOptions options = new LauncherOptions(); options.TargetApplicationPackageFamilyName = packageFamilyName; //Lancer une application bien spécifique par protocole // en fournissant son nom de package bool ok = await Launcher.LaunchUriAsync(protocolUri, options); // Lancer une application bien spécifique(ou non) // par protocole en fournissant un fichier ValueSet inputData = new ValueSet(); var fileToken = SharedStorageAccessManager.AddFile(file); inputData.Add("FileToken", fileToken); ok = await Launcher.LaunchUriAsync(protocolUri, options, inputData); //Lancer une application bien spécifique (ou non) // par protocole et attendre qu’elle nous retourne un objet var launchResult = await Launcher.LaunchUriForResultsAsync(protocolUri, options); //Lancer une application bien spécifique (ou non) en // fournissant l’accès à un fichier await Launcher.LaunchFileAsync(file, options); // Vérifier qu’une application gérant un protocole est bien installée sur le PC var result = await Launcher.QueryUriSupportAsync( protocolUri, LaunchUriType.LaunchUri, packageFamilyName); // Lecture du résultat var appInstalled = result == QueryUriSupportStatus.Success; var appNotInstalled = result == QueryUriSupportStatus.AppNotInstalled; var appUnavailable = result == QueryUriSupportStatus.AppUnavailable; var protocolUnavailable = result == QueryUriSupportStatus.ProtocolUnavailable;
N’oublions pas non plus que ces fonctionnalités sont aussi présentes sur Windows Mobile (car c’est son nouveau nom) : il existe des versions “xxxAndContinueAsync” pour certaines méthodes (par exemple LaunchUriForResultsAndContinueAsync).
Ma nouvelle fonctionnalité préférée est bien sur la possibilité d’appeler une application bien spécifique en lui fournissant un fichier et de pouvoir attendre un résultat ! De plus le code à écrire est relativement simple et je vais vous présenter cette solution dans la suite de l’article.
Activation par protocole et attente de résultat – côté “client”
Voici la partie cliente (application activant une autre application :
// Définition de variable d'aide var protocolUri = new Uri("InfiniteSquare://", UriKind.Absolute); var packageFamilyName = "MonIdDePackage"; var fileUri = new Uri("ms-appx:///NousAInfiniteSquare.file"); var file = await StorageFile.GetFileFromApplicationUriAsync(fileUri); var result = await Launcher.QueryUriSupportAsync( protocolUri, LaunchUriType.LaunchUri, packageFamilyName); if (result != QueryUriSupportStatus.Success) { // opération non concluante return false; } // On lance une app spécifique LauncherOptions options = new LauncherOptions(); options.TargetApplicationPackageFamilyName = packageFamilyName; // On lui donne un fichier ValueSet inputData = new ValueSet(); var fileToken = SharedStorageAccessManager.AddFile(file); inputData.Add("FileToken", fileToken); // On attends le résultat var launchResult = await Launcher.LaunchUriForResultsAsync( protocolUri, options, inputData); if (launchResult.Status != LaunchUriStatus.Success) { // opération non concluante return false; } //lecture du résultat var retourDeLautreApp = launchResult.Result .FirstOrDefault(k => k.Key == "Resultat").Value; return true;
Activation par protocole et attente de résultat – côté “serveur”
Côté serveur, l’application implémentant le protocole, il va falloir recevoir la valeur, la lire et retourner un résultat.
Pour cela, on va surcharger la méthode “OnActivated” de l’application et détecter si l’application est activée via un protocole et s’il faut retourner un résultat. Si c’est le cas, on naviguera vers la page “principale” en fournissant le paramètre d’activation qu’elle utilisera.
protected override void OnActivated(IActivatedEventArgs args) { if (args.Kind == ActivationKind.ProtocolForResults) { Frame rootFrame = Window.Current.Content as Frame; // Créer la frame si elle n'existe pas // navigation classique en passant le paramètre // d'activation rootFrame.Navigate(typeof(MainPage), args); } base.OnActivated(args); }
Dans la page principale, nous allons lire le paramètre d’activation et le stocker dans le bon type. Ensuite, nous pourrons utiliser sa propriété “ProtocolForResultActivation” pour indiquer que l’application a terminé et renvoyer un résultat.
private ProtocolForResultsActivatedEventArgs _activationArgs; protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); // Stockage du paramètre dans le bon type _activationArgs = e.Parameter as ProtocolForResultsActivatedEventArgs; } public void ReturnResult() { // Création du résultat, on pourrait aussi renvoyer // un fichier via un token (comme à l'aller) var returnedData = new ValueSet(); returnedData.Add("MonResultat", "Un objet ici"); // On retourne le résultat à l'application originale _activationArgs.ProtocolForResultsOperation .ReportCompleted(returnedData); }
Il est aussi nécessaire de déclarer cette gestion du protocole dans le fichier manifest de l’application en rajoutant ces lignes :
<Extensions> <uap:Extension Category="Windows.protocol"> <uap:Protocol Name="InfiniteSquare"> <uap:Logo>Assets\InfiniteSquare.png</uap:Logo> </uap:Protocol> </uap:Extension> </Extensions>
Conclusion
Pleins de bonnes nouveautés pour la communication inter-app sur ce SDK Windows 10. Bien sûr il ne s’agit encore que d’une preview mais l’on voit bien que Microsoft a décider d’adresser ce problème de façon sérieuse. Cela va surement nous servir dans nos différents projets B2B. Dans un prochain article nous irons voir une autre nouveauté du SDK pour la communication entre applications d’un même éditeur.
Commentaires