Skip to content

Instantly share code, notes, and snippets.

@bizouarn
Last active March 20, 2025 18:15
Show Gist options
  • Save bizouarn/7e160efb40e8df852d4daf84c3514898 to your computer and use it in GitHub Desktop.
Save bizouarn/7e160efb40e8df852d4daf84c3514898 to your computer and use it in GitHub Desktop.
Qu'est-ce que HResult ? (en c#)

HResult en C#

Qu'est-ce que HResult ?

En C#, un HResult est un entier de 32 bits utilisé pour indiquer des erreurs spécifiques dans des exceptions. Il est principalement utilisé pour les erreurs d'interopérabilité COM et dans les API Windows, permettant ainsi d'identifier de manière unique l'origine et le type de l'erreur.

Structure binaire de HResult

Le HResult est un entier de 32 bits, et chaque partie du nombre a une signification particulière permettant de catégoriser l'erreur.
Il peut être décomposé comme suit :

HResult = S | Facility | Code

S (bit 31) : Sign (1 bit)
Facility (bits 30-16) : Code de fournisseur (15 bits)
Code (bits 15-0) : Code d'erreur spécifique (16 bits)

Voici une explication détaillée de chaque section :

S (bit 31) - Le bit de signe

Ce bit (le bit 31) indique si l'opération a échoué ou réussi.

  • S = 0 : L'opération est réussie (valeur positive).
  • S = 1 : L'opération a échoué (valeur négative).

Lorsque S = 1, cela signifie qu'une erreur est survenue.

Facility (bits 30-16) - Code de fournisseur

Les bits 30 à 16 représentent un code de fournisseur ou de service, qui permet d'identifier le composant ou l'API ayant généré l'erreur.

Exemples de Facility :

0x7 : Système d'exploitation (Windows).
0xA : COM.
0x4 : Application personnalisée.

Code (bits 15-0) - Code d'erreur spécifique

Les bits 15 à 0 (les 16 bits les plus à droite) contiennent le code d'erreur spécifique, qui identifie le problème précis ayant causé l'exception (par exemple "fichier introuvable", "mémoire insuffisante", "accès refusé").

Visualisation binaire

Prenons l'exemple suivant de HResult : 0x80070020 (en hexadécimal).

HResult = 0x80070020
HResult en binaire = 1000 0000 0000 0111 0000 0000 0010 0000

Détaillons cette valeur :

Bit 31 (S) : 1 → Cela signifie que l'erreur est une exception (non succès).
Bits 30-16 (Facility) : 0x7 → Code de fournisseur Windows (erreur système).
Bits 15-0 (Code) : 0x20 → Code d'erreur spécifique.

Le code 0x20 correspond à une erreur de "le fichier est en cours d'utilisation", ce qui est couramment retourné lorsqu'un fichier est verrouillé par un autre processus.

Structure binaire de l'exemple 0x80070020.

Bits 31 30-16 15-0
Valeur 1 0x7 0x20
Description S Facility Code

Exemple d'utilisation de HResult dans un bloc catch

Dans cet exemple, nous allons capturer spécifiquement une exception IOException où le code d'erreur (en l'occurrence 0x20, ce qui correspond à "Le fichier est en cours d'utilisation").

catch (IOException ex) when ((ex.HResult & 0x0000FFFF) == 0x20)
{
    // Code d'erreur 0x20 : Le fichier est en cours d'utilisation
    Console.WriteLine("Erreur : Le fichier est en cours d'utilisation.");
}

Explication du filtre when

L'expression :

(ex.HResult & 0x0000FFFF) == 0x20

Le HResult est un entier 32 bits, et ici nous utilisons un masquage de bits avec 0x0000FFFF pour ne récupérer que les 16 bits de droite (c'est-à-dire le Code d'erreur spécifique). Ensuite, nous comparons cette valeur à 0x20, ce qui correspond au code d'erreur "Le fichier est en cours d'utilisation". Si l'erreur correspond, le bloc catch sera exécuté et le message d'erreur sera affiché.

Conversion d'un HResult en message d'erreur lisible

Vous pouvez également convertir un HResult en un message d'erreur lisible pour l'afficher à l'utilisateur ou pour déboguer.

Par exemple :

int errorCode = ex.HResult;
string message = new System.ComponentModel.Win32Exception(errorCode).Message;
Console.WriteLine($"Erreur : {message}");

Cela génère un message lisible à partir du code d'erreur HResult, ce qui peut être utile pour obtenir une description détaillée de l'erreur.

Résumé

Un HResult est un entier de 32 bits utilisé pour indiquer des erreurs spécifiques dans les exceptions. La structure binaire du HResult se compose de trois parties : S (bit 31 pour le signe), Facility (bits 30-16 pour le fournisseur) et Code (bits 15-0 pour l'erreur spécifique).
L'exemple catch (IOException ex) when ((ex.HResult & 0x0000FFFF) == 0x20) montre comment intercepter spécifiquement des erreurs liées au code 0x20, qui indique que "le fichier est en cours d'utilisation".
Vous pouvez utiliser les masques de bits pour capturer des erreurs précises et utiliser Win32Exception pour obtenir des messages d'erreur détaillés à partir des HResult.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment