Fournisseurs de widgets web

Vous pouvez remplir un widget Windows avec du code HTML servi à partir d’une URL au lieu de définir son corps avec Cartes adaptatives. Votre fournisseur fournit toujours une charge utile JSON de carte adaptative qui spécifie l’URL de contenu. Commencez par Implémenter un fournisseur de widgets dans un application Windows C# ou Implémenter un fournisseur de widgets dans une application Win32 (C++/WinRT), puis ajoutez les fonctionnalités de contenu web décrites ici.

Les API de ressource et de messagerie de cet article ont été introduites dans SDK d'application Windows 1.6.3. Utilisez une version stable actuellement prise en charge à partir des canaux de publication du SDK d’application Windows, et testez sur un appareil Windows 11 avec un hôte de widget qui prend en charge le contenu web.

Les exemples C# sont des fragments pour un fournisseur de widgets de bureau packagé. Ajoutez using Windows.Storage.Streams; et using Microsoft.Windows.Widgets.Providers; au fichier source du fournisseur. Continuez à implémenter IWidgetProvider lorsque vous ajoutez IWidgetResourceProvider ou IWidgetProviderMessage.

Spécifier l’URL de contenu

Envoyez votre charge utile JSON avec WidgetManager.UpdateWidget. Spécifiez un objet de métadonnées avec un champ webUrl qui pointe vers le contenu HTML. Incluez un body de carte adaptative comme contenu de secours pour les hôtes qui ne prennent pas en charge le chargement du contenu web, plutôt que de laisser ces hôtes avec un widget vide.

{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.6",
    "body": [
        {
            "type": "TextBlock",
            "text": "Open the app to view this content.",
            "wrap": true
        }
    ],
    "metadata": {
        "webUrl": "https://contoso.com/widgetprovider.html"
    }
}

La $host.isWebSupported propriété de modèle indique si l’hôte prend en charge le contenu web. Utilisez-le lorsque vous devez adapter davantage la présentation de secours. Pour plus d’informations, consultez propriétés de l’hôte du widget Windows.

Gérer les demandes de ressources

Les fournisseurs de widgets peuvent spécifier une chaîne de filtre de requête web pour un widget dans l’attribut WebRequestFilter de l’élément Definition dans le fichier manifeste du package du fournisseur. Chaque fois que le contenu du widget demande une ressource par URI qui correspond au filtre, la requête est interceptée et redirigée vers l’implémentation du fournisseur de widgets de IWidgetResourceProvider.OnResourceRequested.

Le modèle de filtre utilise le format décrit dans Match Patterns. Utilisez Punycode si nécessaire. Le filtre doit correspondre à l’origine spécifiée par webUrl. Les demandes de tous les types de contenu sont redirigées lorsqu’elles correspondent au filtre, donc limitez le filtre aux ressources gérées par votre fournisseur. Pour plus d’informations, consultez le format XML du manifeste du package du fournisseur de widgets.

Pour gérer les demandes de ressources, les fournisseurs de widgets doivent implémenter l’interface IWidgetResourceProvider .

internal class WidgetProvider : IWidgetProvider, IWidgetResourceProvider

Dans OnResourceRequested, affectez WidgetResourceRequestedArgs.Response à un WidgetResourceResponse contenant la ressource. Cet exemple mappe une URL demandée à une image empaquetée. Incluez Assets\image.png en tant que contenu dans votre package d’application. RandomAccessStreamReference.CreateFromUri prend en charge le schéma ms-appx . Vous pouvez donc créer la référence de flux sans attendre une recherche de fichier.

void IWidgetResourceProvider.OnResourceRequested(WidgetResourceRequestedArgs args)
{
    if (args.Request.Uri == "https://contoso.com/logo-image")
    {
        var imageUri = new System.Uri("ms-appx:///Assets/image.png");
        var content = RandomAccessStreamReference.CreateFromUri(imageUri);
        var response = new WidgetResourceResponse(content, "OK", 200);
        response.Headers.Add("Content-Type", "image/png");
        args.Response = response;
    }
}

Cet exemple synchrone n’a pas besoin d’un différé. Si votre implémentation attend la fin d’une opération asynchrone avant de définir la réponse, appelez GetDeferral avant le retour du rappel et terminez-la dans un bloc finally. Gérez et signalez des échecs asynchrones en fonction de la stratégie de gestion des erreurs de votre application.

Si vous ne définissez pas de réponse, le système récupère la ressource à partir du web. Vous pouvez modifier WidgetResourceRequest.Headers sur args.Request avant cette récupération. Ajoutez uniquement des informations d’identification aux requêtes pour des origines auxquelles vous faites confiance ; une correspondance de filtre seule ne constitue pas une autorisation pour envoyer un jeton.

Gérer les messages vers et à partir du contenu web

Pour recevoir des messages de chaîne du contenu du widget publié à l’aide de la méthode JavaScript window.chrome.webview.postMessage , les fournisseurs de widgets peuvent implémenter l’interface IWidgetProviderMessage et implémenter la méthode OnMessageReceived .

internal class WidgetProvider : IWidgetProvider, IWidgetProviderMessage

Ajoutez le callback à votre classe de fournisseur :

public void OnMessageReceived(WidgetMessageReceivedArgs args)
{
    System.Console.WriteLine($"Message received from widget {args.WidgetContext.Id}: {args.Message}");
}

Envoyez un message au contenu web d’un widget avec WidgetManager.SendMessageToContent. Transmettez l’ID d’instance du widget à partir de WidgetContext.Id, et non l’ID de définition provenant du manifeste du package. Plusieurs instances d’une définition ont des ID d’instance différents.

Appelez la fonction utilitaire suivante à partir d’un rappel de fournisseur, en passant le WidgetContext pour l’instance cible, tel que le contexte reçu par CreateWidget ou OnActionInvoked. Sérialisez les messages structurés plutôt que de construire JSON avec l’interpolation de chaîne, de sorte que les valeurs contenant des guillemets ou des barres obliques inverses restent valides.

private static void SendLocationToWidget(WidgetContext widgetContext, string location)
{
    string message = System.Text.Json.JsonSerializer.Serialize(
        new { current_location = location });
    WidgetManager.GetDefault().SendMessageToContent(widgetContext.Id, message);
}

Le contenu web reçoit le message sous forme de chaîne par le biais de l’événement de window.chrome.webviewmessage. Si vous sérialisez du JSON comme dans cet exemple, analysez ensuite la chaîne dans votre contenu web. Pour plus d’informations, consultez PostWebMessageAsString et le API JavaScript WebView2.

Limitations et exigences

Important

Cette fonctionnalité est disponible uniquement pour les utilisateurs de l’Espace économique européen (EEE).

Les fournisseurs de widgets web ne sont pas des fournisseurs de flux. Pour connaître les flux du tableau de bord et leurs exigences régionales, consultez Tableaux de bord et fournisseurs de flux. Pour le manifeste PWA distinct et le chemin d’implémentation du service-worker, consultez Créer des widgets pilotés par PWA.