Visual Studio 调试器(.NET)的自定义数据可视化工具

重要

从 Visual Studio 2022 版本 17.9 开始,可视化工具现在可以使用新的 VisualStudio.Extensibility 模型以 .NET 6.0+ 编写,以进程外运行。 有关使用新模型创建的扩展,请参阅 创建 Visual Studio 调试器可视化工具中的文档。 如果需要支持较旧版本的 Visual Studio,或者想要将自定义可视化工具作为库 DLL 的一部分交付,请使用本文中的信息,该信息仅适用于较旧的扩展开发模型(VSSDK)。

可视化工具是 Visual Studio 调试器用户界面的一部分,它以适合其数据类型的方式显示变量或对象。 例如, 位图可视化工具解释位图 结构并显示它所表示的图形。 某些可视化工具允许你修改和查看数据。 在调试器中,可视化器由放大镜图标 可视化器图标表示。 可以在 “数据提示”、“调试器 监视 ”窗口或“ 快速监视 ”对话框中选择图标,然后选择相应的对象的相应可视化工具。

除了 标准内置可视化工具之外,还可以从Microsoft、第三方和社区下载更多可视化工具。 还可以编写自己的可视化工具,并将其安装在 Visual Studio 调试器中。

本文提供了可视化工具创建的高级概述。 有关详细说明,请参阅以下文章:

注释

通用 Windows 平台(UWP)和 Windows 8.x 应用不支持自定义可视化工具。

概述

可以为任何托管类的对象编写自定义可视化工具,但ObjectArray除外。

调试器可视化工具的 体系结构 有两个部分:

  • 调试器端在 Visual Studio 调试器中运行,并创建并显示可视化工具用户界面。

    由于 Visual Studio 在 .NET Framework 运行时上执行,因此必须为 .NET Framework 编写此组件。 因此,无法为 .NET Core 编写它。

  • 调试对象端在 Visual Studio 正在调试的进程中运行(调试对象)。 要可视化的数据对象(例如,String 对象)存在于被调试进程中。 调试对象端将对象发送到调试器端,该对象显示在您创建的用户界面中。

    生成此组件的运行时应与调试对象进程将在其中运行(即 .NET Framework 或 .NET Core)的运行时匹配。

调试器端从实现接口IVisualizerObjectProvider接收数据对象。 调试对象端通过对象源发送对象,这是从VisualizerObjectSource派生出来的。

对象提供程序还可以将数据发送回对象源,这样就可以编写可编辑数据的可视化工具。 重写对象提供程序以与表达式计算器和对象源通信。

调试对象端和调试器端利用 Stream 方法,通过将数据对象序列化为 Stream 格式,并将 Stream 格式的数据反序列化回数据对象来相互通信。

仅当类型为开放类型时,才能为泛型类型编写可视化工具。 此限制与使用 DebuggerTypeProxy 特性时的限制相同。 有关详细信息,请参阅 使用 DebuggerTypeProxy 属性

自定义可视化工具可能有安全注意事项。 请参阅 可视化工具安全注意事项

创建调试器端用户界面

若要在调试器端创建可视化器用户界面,请创建一个继承自 DialogDebuggerVisualizer 的类,并重写 Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show 方法以显示用户界面。 可用于 IDialogVisualizerService 在可视化工具中显示 Windows 窗体、对话框和控件。

  1. 使用 IVisualizerObjectProvider 方法获取调试器端的可视化对象。

  2. 创建继承自 DialogDebuggerVisualizer. 的类。

注释

由于以下部分中所述的安全问题,从 Visual Studio 2022 版本 17.11 开始,可视化工具将无法在基类的构造函数中指定 Legacy 格式化程序策略。 从现在起,可视化工具只能使用 JSON 序列化在调试器和调试客户端组件之间进行通信。

  1. 重写Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show方法以显示你的接口。 使用 IDialogVisualizerService 方法在界面中显示 Windows 窗体、对话框和控件。

  2. 应用 DebuggerVisualizerAttribute,为其提供显示可视化工具(DialogDebuggerVisualizer)。

.NET 5.0+ 的特殊调试器端注意事项

默认情况下,自定义可视化工具使用类通过二进制序列化在调试对象BinaryFormatter端之间传输数据。 但是,这种序列化在 .NET 5 及更高版本中被限制,因为人们担心其 无法修复 的漏洞。 此外,在 ASP.NET Core 5 中,它已被标记为完全过时,使用时将抛出异常,如 ASP.NET Core 文档中所述。 本部分介绍确保可视化工具在此方案中仍受支持的步骤。

  • 出于兼容性原因,在上一部分中重写的 Show 方法仍然接受一个 IVisualizerObjectProvider。 但是,从 Visual Studio 2019 版本 16.10 开始,它实际上是类型 IVisualizerObjectProvider3。 因此,将 objectProvider 对象强制转换为更新的接口。

  • 调试对象 (如命令或数据)发送对象时,使用 IVisualizerObjectProvider2.Serialize 方法将其传递给流,它将根据 调试对象 进程的运行时确定要使用的最佳序列化格式。 然后,将流传递给 IVisualizerObjectProvider2.TransferData 方法。

  • 如果调试对象端的可视化组件需要将任何内容返回到调试器端,它将位于TransferData方法返回的Stream对象中。 IVisualizerObjectProvider2.GetDeserializableObjectFrom方法用于从中获取IDeserializableObject实例并根据需要进行处理,或者,如果它是您知道如何反序列化的类型,请使用DeserializeFromJson

请参阅 适用于 .NET 5.0+ 的特殊被调试方注意事项 部分,以了解在不支持二进制序列化时,被调试方 需要进行哪些其他更改。

注释

若要详细了解此问题,请参阅 BinaryFormatter 安全指南

为被调试端创建可视化对象源

在调试器端代码中,编辑 DebuggerVisualizerAttribute并为其提供可视化类型(调试对象源) (VisualizerObjectSource)。 该 Target 属性设置对象源。 如果省略对象源,可视化工具将使用默认对象源。

调试对象端代码包含可视化的对象源。 数据对象可以重写VisualizerObjectSource的方法。 如果要创建独立的可视化工具,则需要调试对象端 DLL。

在调试对象端代码中:

  • 若要让可视化工具编辑数据对象,对象源必须继承 VisualizerObjectSource 并重写 TransferDataCreateReplacementObject 方法。

  • 如果需要在可视化工具中支持多目标,可以在被调试程序端的项目文件中使用以下目标框架标识符 (TFM)。

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

    这些是唯一受支持的 TFM。

.NET 5.0+ 的特殊调试对象端注意事项

重要

由于有关默认使用的基础二进制序列化方法的安全问题,可视化工具可能需要执行其他步骤才能从 .NET 5.0 开始工作。 请在继续之前阅读本 部分

  • 如果可视化工具实现了TransferData方法,请使用VisualizerObjectSource的最新版本中刚刚添加的GetDeserializableObject方法。 它返回的IDeserializableObject有助于确定对象的序列化格式(二进制或 JSON),并用于反序列化基础对象,从而可对其进行使用。

  • 如果被调试端TransferData调用中向调试器端返回数据,请通过Serialize方法将响应序列化到调试器端的流中。