Appeler des API Win32 à partir d’une application Windows C#

La méthode recommandée pour appeler des API Win32 à partir de C# est CsWin32, un générateur source qui produit des wrappers P/Invoke de type sécurisé au moment de la compilation. CsWin32 fonctionne avec n’importe quel type de projet C# (WinUI 3, WPF, WinForms, console ou bibliothèque de classes) et élimine la nécessité d’écrire DllImport manuellement ou LibraryImport de déclarations.

Vous répertoriez dans un fichier texte les noms des fonctions Win32 dont vous avez besoin, et CsWin32 génère automatiquement les signatures, les structures, les constantes et les interfaces COM appropriées à partir des métadonnées du SDK Windows.

Choisir une approche d’interopérabilité

Approach Quand utiliser Avantages Inconvénients
CsWin32 (recommandé) Tout appel d’API Win32/natif à partir de C# Type-safe, généré à partir des métadonnées officielles Windows SDK, gère le marshaling et les structs, AOT-friendly with configuration Nécessite un package NuGet ; le code généré n’est pas visible par défaut
LibraryImport (.NET 7+) Appels ponctuels où vous connaissez la signature exacte Généré à partir du code source, compatible AOT, sans marshaling à l’exécution Vous écrivez et gérez chaque signature manuellement
DllImport (hérité) Code existant ou projets .NET Framework Fonctionne partout, nombreux exemples de la communauté Marshaling à l’exécution, signatures propices aux erreurs
C#/WinRT API du Windows Runtime (Windows.*espaces de noms) Types de .NET projetés, expérience C# naturelle Uniquement pour les API WinRT, pas win32 brutes

Note

La sortie par défaut de CsWin32 utilise le marshaller d'exécution .NET et n'est pas automatiquement compatible avec AOT. Pour NativeAOT ou le découpage, activez CsWin32RunAsBuildTask et DisableRuntimeMarshalling — consultez le guide AOT de CsWin32.

Tip

Si l'API dont vous avez besoin se trouve dans un Windows.* espace de noms (par exemple, Windows.Storage ou Windows.Media), il s'agit d'une API Windows Runtime. Utilisez une projection WinRT au lieu de P/Invoke. Consultez les API d’interopérabilité des appels à partir d’une application .NET.

Prerequisites

  • Visual Studio 2022 (version 17.4 ou ultérieure) ou le SDK .NET 8+
  • Un projet C# existant (WinUI 3, WPF, WinForms ou console)

Note

Cibler le .NET Framework ou .NET Standard ? Définissez <LangVersion>9</LangVersion> (ou une version ultérieure) dans votre fichier de projet, puis ajoutez les packages NuGet System.Memory et System.Runtime.CompilerServices.Unsafe.

Étape 1 : Installer le package NuGet CsWin32

Dans le répertoire de votre projet, exécutez :

dotnet add package Microsoft.Windows.CsWin32

CsWin32 génère du code qui utilise des pointeurs et des contextes non sécurisés. Le package NuGet active automatiquement AllowUnsafeBlocks. Si votre projet définit <AllowUnsafeBlocks>false</AllowUnsafeBlocks>explicitement , supprimez cette ligne ou remplacez-la truepar , sinon le code généré ne sera pas compilé.

Étape 2 : Demander les API dont vous avez besoin

Créez un fichier nommé NativeMethods.txt dans la racine de votre projet (en regard du .csproj fichier). Ajoutez un nom d’API par ligne. Pour cette procédure pas à pas, commencez par une fonction simple :

GetTickCount

Enregistrez le fichier. CsWin32 l’lit au moment de la compilation et génère le wrapper P/Invoke correspondant.

Étape 3 : Appeler l’API générée

Le code généré se trouve dans l’espace de noms Windows.Win32, dans une classe statique appelée PInvoke. Appelez-le comme n’importe quelle autre méthode statique :

using Windows.Win32;

// Get the number of milliseconds since the system started.
uint uptime = PInvoke.GetTickCount();
Console.WriteLine($"System uptime: {uptime} ms");

Générez votre projet. Si le nom de la fonction dans NativeMethods.txt est valide, l’appel compile et s’exécute sans travail supplémentaire.

Pièges courants

« Je ne vois pas le code généré »

CsWin32 est un générateur source , sa sortie n’apparaît pas en tant que fichiers dans votre projet par défaut. Pour inspecter le code généré :

  1. Dans Visual Studio, développez Les analyseurs de dépendances >> Microsoft.Windows. CsWin32 > Microsoft.Windows. CsWin32.SourceGenerator dans Explorateur de solutions.
  2. Vous pouvez également définir <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> dans votre fichier projet pour écrire les sources générées dans le obj/ dossier.

Plateforme cible AnyCPU

Le code généré par CsWin32 fonctionne avec AnyCPU. Vous n’avez pas besoin de modifier votre cible de plateforme pour la plupart des appels Win32.

Obtention d’un HWND dans WinUI 3

De nombreuses API Win32 nécessitent un handle de fenêtre. Dans une application WinUI 3, obtenez le HWND à partir de votre Window instance :

using WinRT.Interop;

var hWnd = WindowNative.GetWindowHandle(this);

Transmettez ensuite hWnd (en tant que HWND ou nint) à la fonction Win32. Pour plus d’informations, consultez Récupérer un handle de fenêtre (HWND).

Personnalisation du comportement CsWin32

Créez un fichier NativeMethods.json à côté de votre fichier texte pour contrôler les options de génération, telles que le marshaling des chaînes larges ou étroites ou les surcharges simplifiées :

{
  "$schema": "https://aka.ms/CsWin32.schema.json",
  "emitSingleFile": false,
  "public": true
}

Consultez la référence de configuration CsWin32 pour toutes les options.

Étapes suivantes