Appeler des API Windows Runtime dans les applications de bureau

Cette rubrique explique comment configurer vos projets d’application de bureau pour utiliser des API Windows Runtime (WinRT) fournies par le système d’exploitation Windows et ajouter des expériences Windows 11 et Windows 10 modernes à vos applications de bureau.

Certaines API Windows Runtime (WinRT) ne sont pas prises en charge dans les applications de bureau. Pour plus d’informations, consultez API Windows Runtime non prises en charge dans les applications de bureau.

Modifier un projet .NET pour utiliser des API d’exécution Windows

Il existe plusieurs options pour les projets .NET :

  • À compter de .NET 6, vous pouvez spécifier le moniker de framework cible (TFM, Target Framework Moniker) dans votre fichier projet pour accéder aux API WinRT. Cette option est prise en charge dans les projets qui ciblent Windows 10 version 1809 ou ultérieure.
  • Pour les versions précédente antérieures de .NET, vous pouvez installer le package NuGet Microsoft.Windows.SDK.Contracts pour ajouter toutes les références nécessaires à votre projet. Cette option est prise en charge dans les projets qui ciblent Windows 10 version 1803 ou ultérieure.
  • Si votre projet cible à la fois .NET 6 (ou ultérieur) et des versions antérieures de .NET, alors vous pouvez configurer le fichier de projet pour qu’il utilise les deux options.

.NET 6 ultérieur : utiliser l’option moniker du framework cible

Cette option est prise en charge uniquement dans les projets qui utilisent .NET 6 (ou une version ultérieure) et ciblent Windows 10 version 1809 ou une version de système d’exploitation ultérieure. En spécifiant un moniker TFM spécifique à la version du système d’exploitation Windows dans le fichier projet, une référence est ajoutée au package cible Windows SDK approprié. Pour plus d’informations générales sur ce scénario, consultez le billet de blog Appel des API Windows dans .NET.

  1. Votre projet étant ouvert dans Visual Studio, cliquez dessus avec le bouton droit dans l’Explorateur de solutions, puis sélectionnez Modifier le fichier de projet. Votre fichier de projet se présente comme suit.

    Note

    L’exemple ci-dessous indique un OutputType ayant pour valeur WinExe, qui spécifie un exécutable GUI Windows (et empêche une fenêtre de console de s’ouvrir quand l’application s’exécute). Si votre application n’a pas d’interface utilisateur graphique, votre OutputType a une valeur différente. Vous pouvez appeler des API WinRT à partir des applications GUI Windows, des applications console et des bibliothèques. En outre, votre valeur pour TargetFramework peut ne pas correspondre exactement à l’exemple ci-dessous.

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFramework>net5.0</TargetFramework>
      </PropertyGroup>
    </Project>
    
  2. Tout en laissant les autres paramètres tels qu’ils sont, remplacez la valeur de l’élément TargetFramework par l’une des chaînes suivantes :

    • net6.0-windows10.0.17763.0 : si votre application cible Windows 10, version 1809.
    • net6.0-windows10.0.18362.0 : si votre application cible Windows 10, version 1903.
    • net6.0-windows10.0.19041.0 : si votre application cible Windows 10, version 2004.
    • net6.0-windows10.0.22000.0 : si votre application cible Windows 11.

    Par exemple, l’élément suivant concerne un projet qui cible Windows 10 version 2004.

    <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
    

    Dans les versions ultérieures de .NET, vous pouvez remplacer la valeur par la version appropriée, par exemple net6.0-windows10.0.19041.0.

  3. Enregistrez vos modifications et fermez le fichier de projet.

API WinRT non prises en charge dans .NET 6 et versions ultérieures

Dans .NET 6 et versions ultérieures, plusieurs API Windows Runtime (WinRT) dans l’espace de noms Windows.UI ne sont pas prises en charge. Pour les API listées ci-dessous, des versions équivalentes des API existent dans l’espace de noms WinUI (Microsoft.UI), par exemple, Microsoft.UI.Text. Les API WinRT suivantes ne sont pas prises en charge dans .NET 6 et versions ultérieures :

Prise en charge de plusieurs versions du système d’exploitation Windows

La propriété TargetFramework spécifique à la version du système d’exploitation Windows détermine la version du SDK Windows avec lequel votre application est compilée. Cette propriété détermine l’ensemble des API accessibles au moment de la build et fournit des valeurs par défaut pour TargetPlatformVersion et TargetPlatformMinVersion (si elles ne sont pas définies explicitement). La propriété TargetPlatformVersion n’a pas besoin d’être définie explicitement dans le fichier projet, car elle est automatiquement définie par la version du système d’exploitation de TargetFramework.

TargetPlatformMinVersion peut être remplacée par une version inférieure à TargetPlatformVersion (déterminée par la version spécifiée dans la propriété TargetFramework). Ceci permet à une application de s’exécuter sur des versions antérieures du système d’exploitation. Par exemple, vous pouvez définir ceci dans votre fichier projet pour prendre en charge une rétrogradation du niveau de votre application avec Windows 10, version 1809.

<Project Sdk="Microsoft.NET.Sdk">
 <PropertyGroup>
   <OutputType>WinExe</OutputType>
   <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
   <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
 </PropertyGroup>
</Project>

Notez que la définition de TargetPlatformMinVersion sur une version inférieure à TargetPlatformVersion induit le risque d’appeler des API non disponibles. Lors de l’appel d’API WinRT qui ne sont pas disponibles sur toutes les versions de système d’exploitation prises en charge, nous vous recommandons d’utiliser ApiInformation pour vérifier leur présence. Pour plus d’informations, consultez Applications s’adaptant aux versions.

Versions antérieures de .NET : installer le package NuGet Microsoft.Windows.SDK.Contracts

Utilisez cette option si votre application utilise .NET Core 3.x ou .NET Framework. Cette option est prise en charge dans les projets qui ciblent Windows 10 version 1803 ou ultérieure.

  1. Assurez-vous que les références de package sont activées :

    1. Dans Visual Studio, cliquez sur Outils -> Gestionnaire de package NuGet -> Paramètres du Gestionnaire de package.
    2. Assurez-vous que PackageReference est sélectionné pour Format de gestion de package par défaut.
  2. Votre projet étant ouvert dans Visual Studio, cliquez dessus avec le bouton droit dans l’Explorateur de solutions, puis sélectionnez Gérer les packages NuGet.

  3. Dans la fenêtre Gestionnaire de packages NuGet, sélectionnez l’onglet Parcourir, puis recherchez Microsoft.Windows.SDK.Contracts.

  4. Une fois le package de Microsoft.Windows.SDK.Contracts trouvé, dans le volet droit de la fenêtre Gestionnaire de packages NuGet, sélectionnez la Version du package à installer en fonction de la version de Windows 10 que vous souhaitez cibler :

    • 10.0.19041.xxxx : choisissez cette version pour Windows 10, version 2004.
    • 10.0.18362.xxxx : choisissez cette version pour Windows 10, version 1903.
    • 10.0.17763.xxxx : choisissez cette version pour Windows 10, version 1809.
    • 10.0.17134.xxxx : choisissez cette version pour Windows 10, version 1803.
  5. Cliquez sur Installer.

Configurer des projets qui ciblent plusieurs versions différentes de .NET

Si votre projet cible à la fois .NET 6 (ou ultérieur) et des versions antérieures (y compris .NET Core 3.x et .NET Framework), alors vous pouvez configurer le fichier de projet de façon à utiliser le moniker de framework cible (TFM) pour extraire automatiquement les références d’API WinRT pour .NET 6 et utiliser le package NuGet Microsoft.Windows.SDK.Contracts pour les versions antérieures.

  1. Votre projet étant ouvert dans Visual Studio, cliquez dessus avec le bouton droit dans l’Explorateur de solutions, puis sélectionnez Modifier le fichier de projet. L’exemple suivant montre un fichier de projet pour une application qui utilise .NET Core 3.1.

    Note

    L’exemple ci-dessous indique un OutputType ayant pour valeur WinExe, qui spécifie un exécutable GUI Windows (et empêche une fenêtre de console de s’ouvrir quand l’application s’exécute). Si votre application n’a pas d’interface utilisateur graphique, votre OutputType a une valeur différente. Vous pouvez appeler des API WinRT à partir des applications GUI Windows, des applications console et des bibliothèques. En outre, votre valeur pour TargetFramework peut ne pas correspondre exactement à l’exemple ci-dessous.

    <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <UseWindowsForms>true</UseWindowsForms>
      </PropertyGroup>
    </Project>
    
  2. Remplacez l’élément TargetFramework du fichier par un élément TargetFrameworks (au pluriel). Dans cet élément, spécifiez les monikers de framework cibles (TFM) pour toutes les versions de .NET que vous ciblez en les séparant par des points virgules.

    • Pour .NET 6 ou ultérieur, utilisez un des monikers de framework cibles (TFM) suivants :
      • net6.0-windows10.0.17763.0 : si votre application cible Windows 10, version 1809.
      • net6.0-windows10.0.18362.0 : si votre application cible Windows 10, version 1903.
      • net6.0-windows10.0.19041.0 : si votre application cible Windows 10, version 2004.
    • Pour .NET Core 3.x, utilisez netcoreapp3.0 ou netcoreapp3.1.
    • Pour le .NET Framework, utilisez net46.

    L’exemple suivant montre comment cibler à la fois .NET Core 3.1 et .NET 6 (pour Windows 10 version 2004).

    <TargetFrameworks>netcoreapp3.1;net6.0-windows10.0.19041.0</TargetFrameworks>
    
  3. Après l’élément PropertyGroup, ajoutez un élément PackageReference, qui inclut une instruction conditionnelle installant le package NuGet Microsoft.Windows.SDK.Contracts pour toutes les versions de .NET Core 3.x ou le .NET Framework ciblé par votre application. L’élément PackageReference doit être un enfant de l’élément ItemGroup. L’exemple suivant montre comment procéder pour .NET Core 3.1.

    <ItemGroup>
      <PackageReference Condition="'$(TargetFramework)' == 'netcoreapp3.1'"
                        Include="Microsoft.Windows.SDK.Contracts"
                        Version="10.0.19041.0" />
    </ItemGroup>
    

    Lorsque vous avez terminé, votre fichier de projet doit se présenter comme suit.

    <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFrameworks>netcoreapp3.1;net6.0-windows10.0.19041.0</TargetFrameworks>
        <UseWPF>true</UseWPF>
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Condition="'$(TargetFramework)' == 'netcoreapp3.1'"
                         Include="Microsoft.Windows.SDK.Contracts"
                         Version="10.0.19041.0" />
      </ItemGroup>
    </Project>
    
  4. Enregistrez vos modifications et fermez le fichier de projet.

Modifier un projet d’application de bureau C++ (Win32) pour utiliser des API Windows Runtime

Utilisez C++/WinRT pour consommer des API WinRT. C++/WinRT est une projection de langage C++17 moderne totalement standard pour les API WinRT, implémentée en tant que bibliothèque basée sur un fichier d’en-tête et conçue pour vous fournir un accès de première classe à l’API Windows moderne.

Pour configurer votre projet pour C++/WinRT :

Pour plus d’informations sur ces options, consultez Prise en charge de Visual Studio pour C++/WinRT et VSIX.

Ajouter des expériences Windows 10

Vous êtes maintenant prêt à ajouter des expériences modernes qui s’activent quand des utilisateurs exécutent votre application sur Windows 10. Utilisez ce flux de conception.

Commencez pas choisir les expériences que vous voulez ajouter

Le est vaste. Par exemple, vous pouvez simplifier votre flux de bons de commande à l’aide d’API de monétisation ou attirer l’attention sur votre application lorsque vous avez quelque chose d’intéressant à partager, par exemple, une nouvelle image publiée par un autre utilisateur.

Notification toast

Même si les utilisateurs ignorent ou ferment votre message, ils peuvent le revoir dans le centre de notifications et cliquer dessus pour ouvrir votre application. Cela rend votre application plus attractive et présente l’avantage supplémentaire de la faire paraître profondément intégrée avec le système d’exploitation. Nous vous présentons le code de cette expérience un peu plus loin dans cet article.

Pour d’autres idées, consultez la Documentation UWP.

Décidez entre améliorer et étendre

Vous nous entendrez souvent utiliser les termes améliorer et étendre. Nous allons donc prendre quelques instants pour expliquer ce qu’ils signifient exactement.

Nous utilisons le terme améliorer pour décrire les API WinRT que vous pouvez appeler directement à partir de votre application de bureau, qu’il s’agisse ou non d’une application empaquetée. Une fois que vous avez choisi une expérience Windows 10, identifiez les API dont vous avez besoin pour la créer, puis vérifiez si elles figurent dans cette liste. Il s’agit d’une liste d’API que vous pouvez appeler directement à partir de votre application de bureau. Si votre API ne figure pas dans cette liste, c’est parce que la fonctionnalité qui y est associée ne peut s’exécuter qu’à l’intérieur d’un processus UWP. Souvent, il s’agit d’API qui affichent du code XAML UWP, comme un contrôle de carte UWP ou une invite de sécurité Windows Hello.

Note

Si les API qui affichent du code XAML UWP ne peuvent généralement pas être appelées directement à partir du bureau, vous pouvez peut-être adopter d’autres approches. Si vous souhaitez héberger des contrôles XAML UWP ou d’autres expériences visuelles personnalisées, vous pouvez utiliser des îlots XAML (à partir de Windows 10, version 1903) et la couche visuelle (à partir de Windows 10, version 1803). Ces fonctionnalités sont utilisables dans des applications de bureau empaquetées ou non.

Si vous avez choisi d’empaqueter votre application de bureau, une autre option consiste à étendre l’application en ajoutant un projet UWP à votre solution. Le projet de bureau est toujours le point d’entrée de votre application, mais le projet UWP vous donne accès à toutes les API qui n’apparaissent pas dans cette liste. L’application de bureau peut communiquer avec le processus UWP en utilisant un service d’application, et nous offrons de nombreux conseils sur la façon de configurer cette fonctionnalité. Si vous souhaitez ajouter une expérience qui requiert un projet UWP, voir Étendre à l’aide de composants UWP.

Contrats API de référence

Si vous pouvez appeler l’API directement à partir de votre application de bureau, ouvrez un navigateur et recherchez la rubrique de référence de cette API. Sous le résumé de l’API, vous trouverez une table décrivant le contrat API pour cette API. Voici un exemple d’une telle table :

Table de contrat API

Si vous avez une application de bureau .NET, ajoutez une référence à ce contrat API et définissez la propriété Copie locale de ce fichier sur la valeur False. Si vous avez un projet C++, ajoutez à vos Autres répertoires Include un chemin d’accès au dossier qui contient ce contrat.

Appelez les API pour ajouter votre expérience

Voici le code qui vous permettrait d’afficher la fenêtre de notification que nous avons examinée plus haut. Ces API s’affichent dans cette liste afin que vous puissiez ajouter ce code à votre application de bureau et l’exécuter immédiatement.

using Windows.Foundation;
using Windows.System;
using Windows.UI.Notifications;
using Windows.Data.Xml.Dom;
...

private void ShowToast()
{
    string title = "featured picture of the day";
    string content = "beautiful scenery";
    string image = "https://picsum.photos/360/180?image=104";
    string logo = "https://picsum.photos/64?image=883";

    string xmlString =
    $@"<toast><visual>
       <binding template='ToastGeneric'>
       <text>{title}</text>
       <text>{content}</text>
       <image src='{image}'/>
       <image src='{logo}' placement='appLogoOverride' hint-crop='circle'/>
       </binding>
      </visual></toast>";

    XmlDocument toastXml = new XmlDocument();
    toastXml.LoadXml(xmlString);

    ToastNotification toast = new ToastNotification(toastXml);

    ToastNotificationManager.CreateToastNotifier().Show(toast);
}
#include <sstream>
#include <winrt/Windows.Data.Xml.Dom.h>
#include <winrt/Windows.UI.Notifications.h>

using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::System;
using namespace winrt::Windows::UI::Notifications;
using namespace winrt::Windows::Data::Xml::Dom;

void UWP::ShowToast()
{
    std::wstring const title = L"featured picture of the day";
    std::wstring const content = L"beautiful scenery";
    std::wstring const image = L"https://picsum.photos/360/180?image=104";
    std::wstring const logo = L"https://picsum.photos/64?image=883";

    std::wostringstream xmlString;
    xmlString << L"<toast><visual><binding template='ToastGeneric'>" <<
        L"<text>" << title << L"</text>" <<
        L"<text>" << content << L"</text>" <<
        L"<image src='" << image << L"'/>" <<
        L"<image src='" << logo << L"'" <<
        L" placement='appLogoOverride' hint-crop='circle'/>" <<
        L"</binding></visual></toast>";

    XmlDocument toastXml;

    toastXml.LoadXml(xmlString.str().c_str());

    ToastNotificationManager::CreateToastNotifier().Show(ToastNotification(toastXml));
}
using namespace Windows::Foundation;
using namespace Windows::System;
using namespace Windows::UI::Notifications;
using namespace Windows::Data::Xml::Dom;

void UWP::ShowToast()
{
    Platform::String ^title = "featured picture of the day";
    Platform::String ^content = "beautiful scenery";
    Platform::String ^image = "https://picsum.photos/360/180?image=104";
    Platform::String ^logo = "https://picsum.photos/64?image=883";

    Platform::String ^xmlString =
        L"<toast><visual><binding template='ToastGeneric'>" +
        L"<text>" + title + "</text>" +
        L"<text>"+ content + "</text>" +
        L"<image src='" + image + "'/>" +
        L"<image src='" + logo + "'" +
        L" placement='appLogoOverride' hint-crop='circle'/>" +
        L"</binding></visual></toast>";

    XmlDocument ^toastXml = ref new XmlDocument();

    toastXml->LoadXml(xmlString);

    ToastNotificationManager::CreateToastNotifier()->Show(ref new ToastNotification(toastXml));
}

Pour en savoir plus sur les notifications, voir Notifications toast adaptatives et interactives.

Prise en charge des bases d’installation Windows XP, Windows Vista et Windows 7/8

Vous pouvez moderniser votre application pour Windows 10 sans avoir à créer une nouvelle branche ni à gérer des bases de code distinctes.

Si vous souhaitez créer des fichiers binaires distincts pour les utilisateurs de Windows 10, utilisez la compilation conditionnelle. Si vous préférez créer un ensemble de fichiers binaires que vous déployez sur tous les utilisateurs de Windows, utilisez des vérifications à l’exécution.

Jetons un coup d’œil à chaque option.

Compilation conditionnelle

Vous pouvez conserver une seule base de code et compiler un ensemble de fichiers binaires uniquement pour les utilisateurs de Windows 10.

D’abord, ajoutez une nouvelle configuration de build à votre projet.

Configuration de build

Pour cette configuration de build, créez une constante pour identifier le code qui appelle des API WinRT.

Pour les projets .NET, la constante s’appelle Constante de compilation conditionnelle.

Constante de compilation conditionnelle

Pour les projets C++, la constante s’appelle Définition du préprocesseur.

Constante de définition de préprocesseur

Ajoutez cette constante devant un bloc de code UWP.

[System.Diagnostics.Conditional("_UWP")]
private void ShowToast()
{
 ...
}
#if _UWP
void UWP::ShowToast()
{
 ...
}
#endif

Le compilateur génère ce code uniquement si cette constante est définie dans votre configuration de build active.

Vérifications à l’exécution

Vous pouvez compiler un ensemble de fichiers binaires pour l’ensemble de vos utilisateurs Windows, quelle que soit la version de Windows exécutée. Votre application appelle des API WinRT uniquement si l’utilisateur l’exécute en tant qu’application empaquetée sur Windows 10.

Le moyen le plus simple d’ajouter à votre code des vérifications à l’exécution consiste à installer ce package Nuget : Desktop Bridge Helpers, puis à utiliser la méthode IsRunningAsUWP() pour désactiver tout le code qui appelle les API WinRT. Pour plus de détails, consultez ce billet de blog : Pont du bureau : identifier le contexte de l’application.

Trouvez des réponses à vos questions

Des questions ? Contactez-nous sur Stack Overflow. Notre équipe supervise ces étiquettes. Vous pouvez également poser vos questions sur nos forums.