Visualiseurs de données personnalisés pour le débogueur Visual Studio (.NET)

Un visualiseur fait partie de l’interface utilisateur du débogueur Visual Studio qui affiche une variable ou un objet de manière appropriée pour son type de données. Par exemple, un visualiseur bitmap interprète une structure bitmap et affiche le graphique qu’elle représente. Certains visualiseurs vous permettent de modifier et de consulter les données. Dans le débogueur, un visualiseur est représenté par une icône de loupe VisualizerIcon. Vous pouvez sélectionner l’icône dans un DataTip, une fenêtre Espion du débogueur ou une boîte de dialogue QuickWatch, puis sélectionner le visualiseur approprié pour l’objet correspondant.

D’autres visualiseurs peuvent être téléchargés auprès de Microsoft en plus des visualiseurs standards intégrés, de fournisseurs tiers et de la communauté. Vous pouvez également écrire vos propres visualiseurs et les installer dans le débogueur Visual Studio.

Cet article fournit une vue d’ensemble générale de la création d’un visualiseur. Pour obtenir des instructions détaillées, consultez plutôt l’article suivant :

Remarque

Les visualiseurs personnalisés ne sont pas pris en charge pour la plateforme Windows universelle (UWP) et les applications Windows 8.x.

Vue d’ensemble

Vous pouvez écrire un visualiseur personnalisé pour un objet de toute classe managée à l’exception de Object et Array.

L'architecture d'un visualiseur du débogueur comporte deux parties :

  • Le côté débogueur s’exécute dans le débogueur Visual Studio et crée et affiche l’interface utilisateur du visualiseur.

    Étant donné que Visual Studio s’exécute sur le runtime .NET Framework, ce composant doit être écrit pour .NET Framework. Pour cette raison, il n’est pas possible de l’écrire pour .NET Core.

  • Le côté élément débogué s’exécute dans le processus que Visual Studio débogue (l’élément débogué). L’objet de données à visualiser (un objet String, par exemple) existe dans le processus de l’élément débogué. Le côté élément débogué envoie l’objet au côté débogueur, qui l’affiche dans l’interface utilisateur que vous créez.

    Le runtime pour lequel vous générez ce composant doit correspondre à celui dans lequel le processus de l’élément débogué s’exécutera, c’est-à-dire .NET Framework ou .NET Core.

Le côté débogueur reçoit l’objet de données à partir d’un fournisseur d’objets qui implémente l’interface IVisualizerObjectProvider. Le côté élément débogué envoie l’objet via la source de l’objet qui est dérivée de VisualizerObjectSource.

Le fournisseur d’objets peut également renvoyer des données à la source de l’objet, ce qui vous permet d’écrire un visualiseur capable de modifier des données. Vous remplacez le fournisseur d’objets pour communiquer avec l’évaluateur d’expression et la source de l’objet.

Le côté élément débogué et le côté débogueur communiquent entre eux par le biais de méthodes Stream qui sérialisent un objet de données en un Stream et désérialisent le Stream dans un objet de données.

Vous pouvez écrire un visualiseur pour un type générique uniquement s’il s’agit d’un type ouvert. Cette restriction est identique à la restriction qui s'applique lorsque vous utilisez l'attribut DebuggerTypeProxy. Pour plus d’informations, consultez Utiliser l’attribut DebuggerTypeProxy.

Les visualiseurs personnalisés pourraient avoir des exigences en matière de sécurité. Consultez Considérations sur la sécurité du visualiseur.

Créer l’interface utilisateur côté débogueur

Pour créer l’interface utilisateur du visualiseur côté débogueur, vous créez une classe qui hérite de DialogDebuggerVisualizer et vous substituez la méthode Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show pour afficher l’interface. Vous pouvez utiliser IDialogVisualizerService pour afficher des formulaires, des boîtes de dialogue et des contrôles Windows dans votre visualiseur.

  1. Utilisez les méthodes IVisualizerObjectProvider pour obtenir l'objet visualisé côté débogueur.

  2. Créez une classe qui hérite de DialogDebuggerVisualizer.

  3. Substituez la méthode Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show pour afficher votre interface. Les méthodes IDialogVisualizerService vous permettent d’afficher des formulaires, des boîtes de dialogue et des contrôles Windows dans votre interface.

  4. Appliquez DebuggerVisualizerAttribute, en le donnant au visualiseur pour l’afficher (DialogDebuggerVisualizer).

Considérations spéciales sur le débogueur pour .NET 5.0+

Les visualiseurs personnalisés transfèrent des données entre le côté élément débogué et le côté débogueur via la sérialisation binaire à l’aide de la classe BinaryFormatter par défaut. Toutefois, ce type de sérialisation est limité dans .NET 5 et versions ultérieures en raison de problèmes de sécurité concernant ses vulnérabilités irréparables. En outre, il a été signalé comme entièrement obsolète dans ASP.NET Core 5 et son utilisation est rejetée comme décrit dans la documentation ASP.NET Core. Cette section décrit les étapes à suivre pour vous assurer que votre visualiseur est toujours pris en charge dans ce scénario.

  • Pour des raisons de compatibilité, la méthode Show qui a été remplacée dans la section précédente accepte toujours un IVisualizerObjectProvider. Toutefois, à partir de Visual Studio 2019 version 16.10, il s’agit en fait du type IVisualizerObjectProvider2. Pour cette raison, castez l’objet objectProvider dans l’interface mise à jour.

  • Lors de l’envoi d’objets, tels que des commandes ou des données, au côté élément débogué, utilisez la méthode IVisualizerObjectProvider2.Serialize pour le passer à un flux. Elle détermine le meilleur format de sérialisation à utiliser en fonction du runtime du processus de l’élément débogué. Ensuite, passez le flux à la méthode IVisualizerObjectProvider2.TransferData.

  • Si le composant du visualiseur côté élément débogué doit retourner quelque chose au côté débogueur, il se trouve dans l’objet Stream retourné par la méthode TransferData. Utilisez la méthode IVisualizerObjectProvider2.GetDeserializableObjectFrom pour obtenir une instance IDeserializableObject à partir de celle-ci et la traiter en fonction des besoins.

Reportez-vous à la section Considérations spéciales relatives au débogage pour .NET 5.0+ pour savoir quelles autres modifications sont requises côté élément débogué lorsque l’utilisation de la sérialisation binaire n’est pas prise en charge.

Remarque

Si vous souhaitez plus d’informations sur le problème, consultez le guide de sécurité BinaryFormatter.

Créer la source de l’objet visualiseur pour le côté élément débogué

Dans le code côté débogueur, modifiez le DebuggerVisualizerAttribute, en lui donnant le type à visualiser (source de l’objet côté élément débogué) (VisualizerObjectSource). La propriété Target définit la source de l’objet. Si vous omettez la source de l’objet, le visualiseur utilisera une source d’objet par défaut.

Le code côté élément débogué contient la source de l’objet qui est visualisée. L’objet de données peut remplacer les méthodes de VisualizerObjectSource. Une DLL côté élément débogué est nécessaire si vous souhaitez créer un visualiseur autonome.

Dans le code côté élément débogué :

  • Pour permettre au visualiseur de modifier des objets de données, la source de l’objet doit hériter de VisualizerObjectSource et remplacer les méthodes TransferData ou CreateReplacementObject.

  • Si vous devez prendre en charge le ciblage multiple dans votre visualiseur, vous pouvez utiliser les monikers de framework cible (TFM) suivants dans le fichier de projet côté élément débogué.

    <TargetFrameworks>net20;netstandard2.0;netcoreapp2.0</TargetFrameworks>
    

    Il s’agit des seuls TFM pris en charge.

Considérations spéciales sur l’élément débogué pour .NET 5.0+

Important

Des étapes supplémentaires peuvent être nécessaires pour qu’un visualiseur fonctionne à partir de .NET 5.0 en raison de problèmes de sécurité liés à la méthode de sérialisation binaire sous-jacente utilisée par défaut. Lisez cette section avant de continuer.

  • Si le visualiseur implémente la méthode TransferData, utilisez la méthode GetDeserializableObject nouvellement ajoutée disponible dans la dernière version de VisualizerObjectSource. Le IDeserializableObject retourné permet de déterminer le format de sérialisation de l’objet (binaire ou JSON) et de désérialiser l’objet sous-jacent afin qu’il puisse être utilisé.

  • Si le côté élément débogué retourne des données au côté débogueur dans le cadre de l’appel TransferData, sérialisez la réponse dans le flux du côté débogueur via la méthode Serialize.