Custom data visualizers for .NET debugging - Visual Studio (Windows) (original) (raw)

Important

Starting with Visual Studio 2022 version 17.9, visualizers can now be written in .NET 6.0+ that run out-of-process using the new VisualStudio.Extensibility model. We encourage visualizer authors to reference the new documentation at Create Visual Studio debugger visualizers unless they want to support older versions of Visual Studio or want to ship their custom visualizers as part of a library DLL.

A visualizer is part of the Visual Studio debugger user interface that displays a variable or object in a manner appropriate to its data type. For example, a bitmap visualizer interprets a bitmap structure and displays the graphic it represents. Some visualizers let you modify as well as view the data. In the debugger, a visualizer is represented by a magnifying glass icon VisualizerIcon. You can select the icon in a DataTip, debugger Watch window, or QuickWatch dialog box, and then select the appropriate visualizer for the corresponding object.

In addition to the standard built-in visualizers, more visualizers might be available for download from Microsoft, third parties, and the community. You can also write your own visualizers and install them in the Visual Studio debugger.

This article provides a high-level overview of visualizer creation. For detailed instructions, see the following articles instead:

Note

Custom visualizers are not supported for Universal Windows Platform (UWP) and Windows 8.x apps.

Overview

You can write a custom visualizer for an object of any managed class except for Object and Array.

The architecture of a debugger visualizer has two parts:

The debugger side receives the data object from an object provider that implements the IVisualizerObjectProvider interface. The debuggee side sends the object through the object source, which is derived from VisualizerObjectSource.

The object provider can also send data back to the object source, which lets you write a visualizer that can edit data. You override the object provider to talk to the expression evaluator and the object source.

The debuggee side and debugger side communicate with each other through Stream methods that serialize a data object into a Stream and deserialize the Stream back into a data object.

You can write a visualizer for a generic type only if the type is an open type. This restriction is the same as the restriction when using the DebuggerTypeProxy attribute. For details, see Use the DebuggerTypeProxy attribute.

Custom visualizers might have security considerations. See Visualizer security considerations.

Create the debugger side user interface

To create the visualizer user interface on the debugger side, you create a class that inherits from DialogDebuggerVisualizer, and override the Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show method to display the interface. You can use IDialogVisualizerService to display Windows forms, dialogs, and controls in your visualizer.

  1. Use IVisualizerObjectProvider methods to get the visualized object on the debugger side.
  2. Create a class that inherits from DialogDebuggerVisualizer.

Note

Due to the security issues described in the section below, starting with Visual Studio 2022 version 17.11, visualizers won't be able to specify the Legacy formatter policy in the base class' constructor. From now on, visualizers can only use JSON serialization to communicate between the debugger and debuggee-side components.

  1. Override the Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show method to display your interface. Use IDialogVisualizerService methods to display Windows forms, dialogs, and controls in your interface.
  2. Apply DebuggerVisualizerAttribute, giving it the visualizer to display (DialogDebuggerVisualizer).

Special debugger side considerations for .NET 5.0+

Custom Visualizers transfer data between the debuggee and debugger sides through binary serialization using the BinaryFormatter class by default. However, that kind of serialization is being curtailed in .NET 5 and above due to security concerns regarding its unfixible vulnerabilities. Moreover, it has been marked completely obsolete in ASP.NET Core 5 and its usage will throw as described in theASP.NET Core Documentation. This section describes the steps you should take to make sure your visualizer is still supported in this scenario.

Please refer to the Special debuggee side considerations for .NET 5.0+ section to learn what other changes are required on the debuggee-side when using Binary Serialization is not supported.

Create the visualizer object source for the debuggee side

In the debugger side code, edit the DebuggerVisualizerAttribute, giving it the type to visualize (the debuggee-side object source) (VisualizerObjectSource). The Target property sets the object source. If you omit the object source, the visualizer will use a default object source.

The debuggee side code contains the object source that gets visualized. The data object can override methods of VisualizerObjectSource. A debuggee side DLL is necessary if you want to create a standalone visualizer.

In the debuggee-side code:

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

These are the only supported TFMs.

Special debuggee side considerations for .NET 5.0+

Important

Additional steps might be needed for a visualizer to work starting in .NET 5.0 due to security concerns regarding the underlying binary serialization method used by default. Please read this section before continuing.