Partager via


Implémenter un fournisseur de flux dans une application Windows C#

Remarque

Certaines informations portent sur le produit en pré-version, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.

Cet article vous guide tout au long de la création d'un fournisseur de flux simple qui inscrit un URI de contenu de flux et implémente l'interface IFeedProvider. Les méthodes de cette interface sont invoquées par le panneau de widgets pour demander des paramètres de chaîne de requête personnalisés, généralement pour prendre en charge les scénarios d'authentification. Les fournisseurs de flux peuvent prendre en charge un seul flux ou plusieurs flux.

Pour implémenter un fournisseur de flux à l'aide de C++/WinRT, consultez Implémenter un fournisseur de flux dans une application win32 (C++/WinRT).

Prérequis

  • Le mode développeur doit être activé sur votre appareil. Pour plus d’informations, consultez Paramètres pour les développeurs.
  • Visual Studio 2026 ou version ultérieure avec la charge de travail de développement d’applications WinUI .

Créer une nouvelle application console C#

Dans Visual Studio, créez un projet. Dans la boîte de dialogue Créer un projet, définissez le filtre de langage sur « C# » et le filtre de plateforme sur Windows, puis sélectionnez le modèle de projet Application console. Nommez le nouveau projet « ExampleFeedProvider. » Pour cette présentation, vérifiez que l'option Placer la solution et le projet dans le même annuaire n'est pas cochée. Lorsque vous y êtes invité, définissez la version cible de .NET sur 6.0.

Une fois que le projet se charge, dans l’Explorateur de solutions, cliquez avec le bouton droit sur le nom du projet, puis sélectionnez Propriétés. Dans la page Général, faites défiler jusqu’à Système d’exploitation cible et sélectionnez « Windows ». Sous Version du système d'exploitation cible, sélectionnez la version 10.022631.2787 ou ultérieure.

Notez que cette procédure pas à pas utilise une application console qui affiche la fenêtre de console lorsque le flux est activé pour faciliter le débogage. Lorsque vous êtes prêt à publier votre application fournisseur de flux, vous pouvez convertir l'application console en application Windows en suivant les étapes décrites dans Convertir votre application console en application Windows.

Ajouter des références au package NuGet de SDK d'application Windows

Cet exemple utilise la dernière version stable du package NuGet du SDK d’application Windows. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur Dépendances et sélectionnez Gérer les packages NuGet.... Dans le gestionnaire de package NuGet, sélectionnez l’onglet Parcourir et recherchez « Microsoft.WindowsAppSDK ». Sélectionnez la dernière version stable dans la liste déroulante Version, puis cliquez sur Installer.

Ajouter une classe FeedProvider pour gérer les opérations de flux

Dans Visual Studio, cliquez avec le bouton droit sur le projet ExampleFeedProvider dans l’Explorateur de solutions et sélectionnez Ajouter->Classe. Dans la boîte de dialogue Ajouter une classe, nommez la classe « FeedProvider », puis cliquez sur Ajouter. Dans le fichier FeedProvider.cs généré, mettez à jour la définition de classe pour indiquer qu'elle implémente l'interface IFeedProvider.

CréeZ un CLSID qui sera utilisé pour identifier votre fournisseur de flux pour l'activation COM. Générez un GUID dans Visual Studio en accédant à Outils->Créer un GUID. Enregistrez ce GUID dans un fichier texte à utiliser ultérieurement lors de l'empaquetage de l'application du fournisseur de flux. Remplacez le GUID dans les annotations de la classe FeedProvider illustrée dans l'exemple suivant.

// FeedProvider.cs
using Microsoft.Windows.Widgets.Feeds.Providers;
...
[ComVisible(true)]
[ComDefaultInterface(typeof(IFeedProvider))]
[Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]
public sealed class FeedProvider : IFeedProvider

Implémenter les méthodes IFeedProvider

Dans les sections suivantes, nous allons implémenter les méthodes de l'interface IFeedProvider.

Remarque

La validité des objets passés dans les méthodes de rappel de l'interface IFeedProvider n'est garantie que pendant l'exécution de la méthode de rappel. Vous ne devez pas stocker les références à ces objets, car leur comportement en dehors du contexte du rappel n’est pas défini.

OnFeedProviderEnabled

La méthode OnFeedProviderEnabled est appelée lorsqu'un flux associé au fournisseur est créé par l'hôte du panneau de widgets. Dans l'implémentation de cette méthode, générez une chaîne de requête avec les paramètres qui seront transmis à l'URL qui fournit le contenu du flux, y compris les jetons d'authentification nécessaires. Créez une instance de CustomQueryParametersUpdateOptions, en passant le FeedProviderDefinitionId à partir des arguments de l'événement qui identifient le flux activé et la chaîne de requête. Obtenez le FeedManager par défaut et appelez SetCustomQueryParameters pour inscrire les paramètres de chaîne de requête auprès du panneau de widgets.

// FeedProvider.cs

public void OnFeedProviderEnabled(FeedProviderEnabledArgs args)
{
    Console.WriteLine($"{args.FeedProviderDefinitionId} feed provider was enabled.");
    var updateOptions = new CustomQueryParametersUpdateOptions(args.FeedProviderDefinitionId, "param1&param2");
    FeedManager.GetDefault().SetCustomQueryParameters(updateOptions);
}

Lors de la désactivation du fournisseur de flux

OnFeedProviderDisabled est appelé lorsque le Panneau de widgets constate que tous les flux de ce fournisseur ont été désactivés. Les fournisseurs de flux ne sont pas tenus d'effectuer des actions en réponse à cet appel de méthode. L'appel de méthode peut être utilisé à des fins de télémétrie ou pour mettre à jour les paramètres de chaîne de requête ou révoquer des jetons d'authentification, si nécessaire. Si l'application prend uniquement en charge un seul fournisseur de flux ou si tous les fournisseurs de flux pris en charge par l'application ont été désactivés, l'application peut se quitter en réponse à ce rappel.

// FeedProvider.cs
public void OnFeedProviderDisabled(FeedProviderDisabledArgs args)
{
    Console.WriteLine($"{args.FeedProviderDefinitionId} feed provider was disabled.");
}

OnFeedEnabled (Activation du flux), OnFeedDisabled (Désactivation du flux)

OnFeedEnabled et OnFeedDisabled sont appelés par le panneau de widgets lorsqu'un flux est activé ou désactivé. Les fournisseurs de flux ne sont pas tenus d'effectuer des actions en réponse à ces appels de méthode. L'appel de méthode peut être utilisé à des fins de télémétrie ou pour mettre à jour les paramètres de chaîne de requête ou révoquer des jetons d'authentification, si nécessaire.

// FeedProvider.cs
public void OnFeedEnabled(FeedEnabledArgs args)
{
    Console.WriteLine($"{args.FeedDefinitionId} feed was enabled.");
}

// FeedProvider.cs
public void OnFeedDisabled(FeedDisabledArgs args)
{
    Console.WriteLine($"{args.FeedDefinitionId} feed was disabled.");
}

OnCustomQueryParametersRequested

OnCustomQueryParametersRequested est déclenché lorsque le panneau de widgets détermine que les paramètres de requête personnalisés associés au fournisseur de flux doivent être actualisés. Par exemple, cette méthode peut être déclenchée si l'opération de récupération (fetch) du contenu du flux à partir du service Web distant échoue. La propriété FeedProviderDefinitionId de CustomQueryParametersRequestedArgs passée à cette méthode spécifie le flux pour lequel les paramètres de chaîne de requête sont demandés. Le fournisseur doit régénérer la chaîne de requête et la transmettre au panneau de widgets en appelant SetCustomQueryParameters.

// FeedProvider.cs

public void OnCustomQueryParametersRequested(CustomQueryParametersRequestedArgs args)
{
    Console.WriteLine($"CustomQueryParamaters were requested for {args.FeedProviderDefinitionId}.");
    var updateOptions = new CustomQueryParametersUpdateOptions(args.FeedProviderDefinitionId, "param1&param2");
    FeedManager.GetDefault().SetCustomQueryParameters(updateOptions);
}

Implémenter une fabrique de classes qui instancie FeedProvider à la demande

Pour que l'hôte du flux communique avec notre fournisseur de flux, nous devons appeler CoRegisterClassObject. Cette fonction nous oblige à créer une implémentation de IClassFactory qui créera un objet de classe pour notre classe FeedProvider. Nous allons implémenter notre fabrique de classes dans une classe d’assistance autonome.

Dans Visual Studio, cliquez avec le bouton droit sur le projet ExampleFeedProvider dans l’Explorateur de solutions et sélectionnez Ajouter->Classe. Dans la boîte de dialogue Ajouter une classe, nommez la classe FactoryHelper, puis cliquez sur Ajouter.

Remplacez le contenu du fichier FactoryHelper.cs par le code ci-après. Ce code définit l'interface IClassFactory et implémente ses deux méthodes, CreateInstance et LockServer. Ce code est typiquement générique pour l'implémentation d'une fabrique de classes et n'est pas spécifique aux fonctionnalités d'un fournisseur de flux, sauf que nous indiquons que l'objet de classe en cours de création implémente l'interface IFeedProvider.

// FactoryHelper.cs
using Microsoft.Windows.Widgets.Feeds.Providers;
using System.Runtime.InteropServices;
using WinRT;

namespace ExampleFeedProvider
{
    namespace Com
    {
        static class Guids
        {
            public const string IClassFactory = "00000001-0000-0000-C000-000000000046";
            public const string IUnknown = "00000000-0000-0000-C000-000000000046";
        }

        [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid(Guids.IClassFactory)]
        internal interface IClassFactory
        {
            [PreserveSig]
            int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject);
            [PreserveSig]
            int LockServer(bool fLock);
        }

        static class ClassObject
        {
            public static void Register(Guid clsid, object pUnk, out uint cookie)
            {
                [DllImport("ole32.dll")]
                static extern int CoRegisterClassObject(
                    [MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
                    [MarshalAs(UnmanagedType.IUnknown)] object pUnk,
                    uint dwClsContext,
                    uint flags,
                    out uint lpdwRegister);

                int result = CoRegisterClassObject(clsid, pUnk, 0x4, 0x1, out cookie);
                if (result != 0)
                {
                    Marshal.ThrowExceptionForHR(result);
                }
            }

            public static int Revoke(uint cookie)
            {
                [DllImport("ole32.dll")]
                static extern int CoRevokeClassObject(uint dwRegister);

                return CoRevokeClassObject(cookie);
            }
        }
    }

    internal class FeedProviderFactory<T> : Com.IClassFactory
            where T : IFeedProvider, new()
    {
        public int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject)
        {
            ppvObject = IntPtr.Zero;

            if (pUnkOuter != IntPtr.Zero)
            {
                Marshal.ThrowExceptionForHR(CLASS_E_NOAGGREGATION);
            }

            if (riid == typeof(T).GUID || riid == Guid.Parse(Com.Guids.IUnknown))
            {
                // Create the instance of the .NET object
                ppvObject = MarshalInspectable<IFeedProvider>.FromManaged(new T());
            }
            else
            {
                // The object that ppvObject points to does not support the
                // interface identified by riid.
                Marshal.ThrowExceptionForHR(E_NOINTERFACE);
            }

            return 0;
        }

        int Com.IClassFactory.LockServer(bool fLock)
        {
            return 0;
        }

        private const int CLASS_E_NOAGGREGATION = -2147221232;
        private const int E_NOINTERFACE = -2147467262;
    }
}

Inscrire l'objet de classe de fournisseur de flux auprès d'OLE

Dans le fichier Program.cs de notre exécutable, nous allons appeler CoRegisterClassObject pour inscrire notre fournisseur de flux auprès d'OLE, afin que le panneau de widgets puisse interagir avec lui. Remplacez le contenu de Program.cs par le code suivant. Cela utilise l'interface FeedProviderFactory que nous avons définie à l'étape précédente pour inscrire la classe d'assistance FeedProvider . À des fins de débogage, cet exemple appelle GetEnabledFeedProviders sur l'instance FeedManager par défaut pour obtenir la liste des objets FeedProviderInfo représentant les fournisseurs de flux activés. Il effectue une boucle via les fournisseurs de flux activés, à l'aide de la propriété EnabledFeedDefinitionIds pour répertorier tous les identifiants de flux activés.

// Program.cs

using Microsoft.Windows.Widgets.Feeds.Providers;
using Microsoft.Windows.Widgets.Providers;
using System; 
using System.Runtime.InteropServices;

namespace ExampleFeedProvider
{

    public static class Program
    {
        [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();

        [MTAThread]
        static void Main(string[] args)
        {
            Console.WriteLine("FeedProvider Starting...");
            if (args.Length > 0 && args[0] == "-RegisterProcessAsComServer")
            {
                WinRT.ComWrappersSupport.InitializeComWrappers();

                uint registrationHandle;
                var factory = new FeedProviderFactory<FeedProvider>();
                Com.ClassObject.Register(typeof(FeedProvider).GUID, factory, out registrationHandle);

                Console.WriteLine("Feed Provider registered.");

                var existingFeedProviders = FeedManager.GetDefault().GetEnabledFeedProviders();
                if (existingFeedProviders != null)
                {
                    Console.WriteLine($"There are {existingFeedProviders.Length} FeedProviders currently outstanding:");
                    foreach (var feedProvider in existingFeedProviders)
                    {
                        Console.WriteLine($"  ProviderId: {feedProvider.FeedProviderDefinitionId}, DefinitionIds: ");
                        var m = WidgetManager.GetDefault().GetWidgetIds();
                        if (feedProvider.EnabledFeedDefinitionIds != null)
                        {
                            foreach (var enabledFeedId in feedProvider.EnabledFeedDefinitionIds)
                            {
                                Console.WriteLine($" {enabledFeedId} ");
                            }
                        }
                    }
                }
                if (GetConsoleWindow() != IntPtr.Zero)
                {
                    Console.WriteLine("Press ENTER to exit.");
                    Console.ReadLine();
                }
                else
                {
                    while (true)
                    {
                        // You should fire an event when all the outstanding
                        // FeedProviders have been disabled and exit the app.
                    }
                }
            }
            else
            {
                Console.WriteLine("Not being launched to service Feed Provider... exiting.");
            }
        }
    }
}

Notez que cet exemple de code importe la fonction GetConsoleWindow pour déterminer si l’application s’exécute en tant qu’application console, le comportement par défaut de cette procédure pas à pas. Si la fonction retourne un pointeur valide, nous consignons des informations de débogage sur la console. Sinon, l’application s’exécute en tant qu’application Windows. Dans ce cas, nous attendons l'événement que nous avons défini dans la méthode OnFeedProviderDisabled lorsque la liste des flux activés est vide, puis nous quittons l'application. Pour plus d’informations sur la conversion de l’exemple d’application console en application Windows, consultez Convertir votre application console en application Windows.

Packager votre application de fournisseur de flux

Dans la version actuelle, seules les applications packagées peuvent être inscrites en tant que fournisseurs de flux. Les étapes suivantes vous présentent le processus d'empaquetage de votre application et de mise à jour du manifeste de l'application pour inscrire votre application auprès du système d'exploitation en tant que fournisseur de flux.

Créer un projet d’empaquetage MSIX

Dans l’Explorateur de solutions, cliquez avec le bouton droit sur votre solution et sélectionnez Ajouter->Nouveau projet.... Dans la boîte de dialogue Ajouter un nouveau projet, sélectionnez le modèle « Projet de création de packages d’applications Windows », puis cliquez sur Suivant. Définissez le nom du projet comme suit « ExampleFeedProviderPackage » et cliquez sur Créer. Lorsque vous y êtes invité, définissez la version cible sur la version 22621 ou ultérieure, puis cliquez sur OK. Ensuite, faites un clic droit sur le projet ExampleFeedProviderPackage, puis sélectionnez Ajouter->Référence de projet. Sélectionnez le projet ExampleFeedProvider, puis cliquez sur OK.

Ajouter une référence de package de SDK d’application Windows au projet d’empaquetage

Vous devez ajouter une référence au package NuGet du SDK d’application Windows au projet d’empaquetage MSIX. Dans l'Explorateur de solutions, double-cliquez sur le projet ExampleFeedProviderPackage pour ouvrir le fichier ExampleFeedProviderPackage.wapproj Ajoutez le code XML suivant dans l’élément Project.

<!--ExampleWidgetProviderPackage.wapproj-->
<ItemGroup>
    <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231116003-experimentalpr">
        <IncludeAssets>build</IncludeAssets>
    </PackageReference>  
</ItemGroup>

Remarque

Vérifiez que la version spécifiée dans l’élément PackageReference correspond à la dernière version stable que vous avez référencée à l’étape précédente.

Si la bonne version du SDK d'application Windows est déjà installée sur l'ordinateur et que vous ne souhaitez pas regrouper le runtime du SDK dans votre package, vous pouvez spécifier la dépendance de package dans le fichier Package.appxmanifest pour le projet ExampleFeedProviderPackage.

<!--Package.appxmanifest-->
...
<Dependencies>
...
    <PackageDependency Name="Microsoft.WindowsAppRuntime.1.5.233430000-experimental1" MinVersion="2000.638.7.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
...
</Dependencies>
...

Mettre à jour le manifeste du package

Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le fichier Package.appxmanifest et sélectionnez Afficher le code pour ouvrir le fichier XML du manifeste. Ensuite, vous devez ajouter des déclarations d’espace de noms pour les extensions de package d’application que nous allons utiliser. Ajoutez les définitions d’espace de noms suivantes à l’élément Package de niveau supérieur.

<!-- Package.appmanifest -->
<Package
  ...
  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
  xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"

À l’intérieur de l’élément Application, créez un élément vide nommé Extensions. Assurez-vous que cela arrive après la balise de fermeture de uap:VisualElements.

<!-- Package.appxmanifest -->
<Application>
...
    <Extensions>

    </Extensions>
</Application>

La première extension que nous devons ajouter est l’extension ComServer. Cela enregistre le point d’entrée de l’exécutable auprès du système d’exploitation. Cette extension est l’application empaquetée équivalente à l’inscription d’un serveur COM en définissant une clé de Registre et n’est pas spécifique aux fournisseurs de widgets. Ajoutez l’élément com:Extension suivant en tant qu’enfant de l’élément Extensions. Remplacez le GUID dans l'attribut Id de l'élément com:Class par le GUID que vous avez généré à l'étape précédente lors de la définition de la classe FeedProvider.

<!-- Package.appxmanifest -->
<Extensions>
    <com:Extension Category="windows.comServer">
        <com:ComServer>
            <com:ExeServer Executable="ExampleFeedProvider\ExampleFeedProvider.exe" Arguments="-RegisterProcessAsComServer" DisplayName="C# Feed Provider App">
                <com:Class Id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" DisplayName="FeedProvider" />
            </com:ExeServer>
        </com:ComServer>
    </com:Extension>
</Extensions>


Ensuite, ajoutez l'extension qui inscrit l'application en tant que fournisseur de flux. Collez l’élément uap3:Extension dans l’extrait de code suivant, en tant qu’enfant de l’élément Extensions. Veillez à remplacer l’attribut ClassId de l’élément COM par le GUID que vous avez utilisé lors des étapes précédentes.

<!-- Package.appxmanifest -->
<Extensions>
    ...
    <uap3:Extension Category="windows.appExtension">
        <uap3:AppExtension Name="com.microsoft.windows.widgets.feeds" DisplayName="ContosoFeed" Id="com.examplewidgets.examplefeed" PublicFolder="Public">
            <uap3:Properties>
                <FeedProvider Icon="ms-appx:Assets\StoreLogo.png" Description="FeedDescription">
                    <Activation>
                        <!-- Apps exports COM interface which implements IFeedProvider -->
                        <CreateInstance ClassId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" />
                    </Activation>
                    <Definitions>
                        <Definition Id="Contoso_Feed"
                            DisplayName="Contoso_Feed Feed"
                            Description="Feed representing Contoso"
                            ContentUri="https://www.contoso.com/"
                            Icon="ms-appx:Images\StoreLogo.png">
                        </Definition>
                        <Definition Id="Fabrikam_Feed"
                            DisplayName="Fabrikam Feed"
                            Description="Feed representing Example"
                            ContentUri="https://www.fabrikam.com/"
                            Icon="ms-appx:Images\StoreLogo.png">
                        </Definition>
                    </Definitions>
                </FeedProvider>
            </uap3:Properties>
        </uap3:AppExtension>
    </uap3:Extension>
</Extensions>

Pour obtenir des descriptions détaillées et des informations de format pour tous ces éléments, consultez Format XML du manifeste du package du fournisseur de flux.

Test de votre fournisseur de flux

Vérifiez que vous avez sélectionné l’architecture qui correspond à votre machine de développement dans la liste déroulante Plateformes de solution, par exemple « x64 ». Dans l’Explorateur de solutions, cliquez avec le bouton droit sur votre solution et sélectionnez Générer la solution. Une fois cette opération effectuée, cliquez avec le bouton droit sur ExempleWidgetProviderPackage, puis sélectionnez Déployer. L'application console doit démarrer lors du déploiement et vous verrez que les flux sont activés dans la sortie de la console. Ouvrez le panneau de widgets ; vous devriez voir les nouveaux flux dans les onglets en haut de la section flux.

Débogage de votre fournisseur de flux

Une fois que vous avez épinglé vos flux, la plateforme de widget démarre votre application de fournisseur de flux afin de recevoir et d'envoyer des informations pertinentes sur le flux. Pour déboguer le flux en cours d'exécution, vous pouvez attacher un débogueur à l'application du fournisseur de flux en cours d'exécution, ou configurer Visual Studio pour démarrer automatiquement le débogage du processus du fournisseur de flux une fois qu'il a démarré.

Pour se connecter au processus en cours d’exécution :

  1. Dans Visual Studio, cliquez sur Déboguer -> Attacher à un processus.
  2. Filtrez les processus et recherchez l'application de fournisseur de flux souhaitée.
  3. Attachez le débogueur.

Pour attacher automatiquement le débogueur au processus lors de son démarrage initial :

  1. Dans Visual Studio, cliquez sur Déboguer -> Autres cibles de débogage -> Déboguer le package d’application installé.
  2. Filtrez les packages et recherchez le package de fournisseur de flux souhaité.
  3. Sélectionnez-le et cochez la case Ne pas lancer, mais déboguer mon code lorsqu'il démarre.
  4. Cliquez sur Joindre.

Convertir votre application console en application Windows

Pour convertir l'application console créée dans cette procédure pas à pas en application Windows, faites un clic droit sur le projet ExampleFeedProvider dans l'Explorateur de solutions, puis sélectionnez Propriétés. Sous Application->Général, remplacez le Type de sortie « Application console » en « Application Windows ».

Capture d'écran montrant les propriétés du projet de fournisseur de flux C# avec le type de sortie défini sur Application Windows.

Publication de votre application de fournisseur de flux

Une fois que vous avez développé et testé votre fournisseur de flux, vous pouvez publier votre application sur le Microsoft Store afin que les utilisateurs puissent installer vos flux sur leurs appareils. Pour obtenir des instructions pas à pas sur la publication d’une application, consultez Publier votre application dans le Microsoft Store.

Collection de flux de données

Une fois que votre application a été publiée sur le Microsoft Store, vous pouvez demander à votre application d’être incluse dans la collection de flux du Windows Store qui aide les utilisateurs à découvrir les applications qui présentent des flux Windows. Pour soumettre votre demande, consultez Soumettre votre flux/carte pour l'ajout à la Collection de la Boutique.