演练:使用 C 编写可视化工具#

重要

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

本演练演示如何使用 C# 编写简单的可视化工具。 在本演练中创建的可视化工具使用 Windows 窗体显示字符串的内容。 这个简单的字符串可视化工具本身并不特别有用,但它显示了为其他数据类型创建更有用的可视化工具所必须遵循的基本步骤。

注释

你看到的对话框和菜单命令可能与“帮助”中所述的命令不同,具体取决于你的活动设置或版本。 若要更改设置,请转到 “工具” 菜单,然后选择“ 导入和导出设置”。 有关详细信息,请参阅 “重置设置”。

可视化工具代码必须放置在调试器读取的 DLL 文件中。 因此,第一步是为 DLL 创建类库项目。

手动创建可视化工具

完成以下任务以创建可视化工具。

创建类库项目

  1. 若要创建新的类库项目,请选择“ 文件>新建>项目”。

  2. 在语言下拉列表中,选择 C#

  3. 在搜索框中,输入 类库。 选择 类库(.NET Framework), 然后选择“ 下一步”。

  4. 在对话框中,输入名称 MyFirstVisualizer,然后选择“ 创建”。

对于可视化工具项目,请确保选择一个 .NET Framework 类库,而不是 .NET。 尽管可视化工具需要为 .NET Framework,但调用应用可以是 .NET。

创建类库后,必须添加对 Microsoft.VisualStudio.DebuggerVisualizers.DLL 文件的引用,以便可以使用其中定义的类。 在添加引用之前,必须重命名某些类以使用有意义的名称。

重命名Class1.cs并添加 Microsoft.VisualStudio.DebuggerVisualizers

  1. 解决方案资源管理器中,右键单击Class1.cs并选择上下文菜单上的 “重命名 ”。

  2. 将名称从Class1.cs更改为有意义的内容,例如DebuggerSide.cs。

    注释

    Visual Studio 会自动更改DebuggerSide.cs中的类声明以匹配新文件名。 如果看到提示完成作,请选择“ ”。

  3. 解决方案资源管理器中,右键单击 “引用 ”,然后选择快捷菜单上的 “添加引用 ”。

  4. 在“ 添加引用 ”对话框中的“ 浏览 ”选项卡上,选择“ 浏览 ”并找到Microsoft.VisualStudio.DebuggerVisualizers.DLL。

    可以在 Visual Studio 的安装目录<\Common7\IDE\PublicAssemblies 子目录中找到 DLL>

  5. 选择“确定”

  6. 在DebuggerSide.cs中,将以下内容添加到 using 指令:

    using Microsoft.VisualStudio.DebuggerVisualizers;
    

现在,你已准备好创建调试器端代码。 此代码在调试器中运行,以显示要可视化的信息。 首先,您需要更改 DebuggerSide 对象的声明,以配置从基类 DialogDebuggerVisualizer 的继承。

继承自 DialogDebuggerVisualizer

  1. 在DebuggerSide.cs中,转到以下代码行:

    public class DebuggerSide
    
  2. 将代码更改为:

    public class DebuggerSide : DialogDebuggerVisualizer
    
  3. 添加一个空构造函数,以便可以传递给基类的构造函数的序列化策略,该策略将用于在可视化工具组件之间通信。

    public DebuggerSide() : base(FormatterPolicy.NewtonsoftJson) // or FormatterPolicy.Json
    {
    }
    

    注释

    由于 .NET 5.0+ 的特殊调试器端注意事项中所述的安全问题,从 Visual Studio 2022 版本 17.11 开始,可视化工具将无法指定 Legacy 格式化程序策略。

  4. DialogDebuggerVisualizer 有一个必须重写的抽象方法(Show)。

重写 DialogDebuggerVisualizer.Show 方法

public class DebuggerSide中,添加以下 方法:

protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
{
}

该方法 Show 包含实际创建可视化工具对话框或其他用户界面的代码,并显示已从调试器传递到可视化工具的信息。 必须添加创建对话框并显示信息的代码。 在本演练中,你将使用 Windows 窗体消息框。 首先,必须添加 System.Windows.Forms 的引用和 using 指令。

添加 System.Windows.Forms

  1. 解决方案资源管理器中,右键单击 “引用 ”,然后选择快捷菜单上的 “添加引用 ”。

  2. 在“ 添加引用 ”对话框中的“ 浏览 ”选项卡上,选择“ 浏览”,找到System.Windows.Forms.DLL。

    可以在 C:\Windows\Microsoft.NET\Framework\v4.0.30319 中找到 DLL。

  3. 选择“确定”

  4. 在DebuggerSide.cs中,将以下内容添加到 using 指令:

    using System.Windows.Forms;
    

现在,添加一些代码来创建和显示可视化工具的用户界面。 由于此示例是你的第一个可视化工具,因此你可以保持用户界面简单并使用 Message Box。

在对话框中显示可视化工具输出

  1. Show 方法中,添加以下代码行:

    MessageBox.Show(objectProvider.GetObject().ToString());
    

    此示例代码不包括错误处理。 应在实际可视化工具或任何其他类型的应用程序中包括错误处理。

  2. “生成 ”菜单上,选择“ 生成 MyFirstVisualizer”。 项目应成功构建。 在继续之前更正任何生成错误。

调试器端代码现已完成。 不过,还有一个步骤:属性需要指示被调试程序端哪个类集合包含可视化器。

添加类型以可视化调试对象端代码

在调试器端的代码中,使用 DebuggerVisualizerAttribute 特性来为被调试对象指定要可视化的类型。 该 Target 属性设置要显示的类型。

  1. 将以下属性代码添加到DebuggerSide.cs, 在using指令之后但在namespace MyFirstVisualizer之前:

    [assembly:System.Diagnostics.DebuggerVisualizer(
    typeof(MyFirstVisualizer.DebuggerSide),
    typeof(VisualizerObjectSource),
    Target = typeof(System.String),
    Description = "My First Visualizer")]
    
  2. “生成 ”菜单上,选择“ 生成 MyFirstVisualizer”。 项目应成功构建。 在继续之前更正任何生成错误。

    此时,第一个可视化工具已完成。 如果已正确执行这些步骤,则可以生成可视化工具并将其安装到 Visual Studio 中。 但是,在将可视化工具安装到 Visual Studio 之前,应对其进行测试以确保其正常运行。 现在创建一个测试工具来运行可视化工具,而无需将其安装到 Visual Studio 中。

添加测试方法以显示可视化工具

  1. 将以下方法添加到类 public DebuggerSide

    public static void TestShowVisualizer(object objectToVisualize)
    {
       VisualizerDevelopmentHost visualizerHost = new VisualizerDevelopmentHost(objectToVisualize, typeof(DebuggerSide));
       visualizerHost.ShowVisualizer();
    }
    
  2. “生成 ”菜单上,选择“ 生成 MyFirstVisualizer”。 项目应成功构建。 在继续之前更正任何生成错误。

    接下来,必须创建一个可执行项目来调用可视化工具 DLL。 为简单起见,请使用控制台应用程序项目。

将控制台应用程序项目添加到解决方案

  1. 在解决方案资源管理器中,右键单击解决方案,选择 “添加”,然后选择“ 新建项目”。

  2. 选择 “文件>新建>项目”。 在语言下拉列表中,选择 C#。 在搜索框中,键入 控制台应用,然后选择 控制台应用(.NET Framework) 或适用于 .NET 的 控制台应用程序 。 选择“下一步”。 在出现的对话框中,键入名称 MyTestConsole,然后选择“ 创建”。

注释

若要使用测试工具轻松测试可视化工具,请创建 .NET Framework 控制台应用。 可以改为创建 .NET 控制台应用,但稍后所述的测试工具尚不支持 .NET,因此需要安装可视化工具来测试它。 对于 .NET 控制台应用,请先在此处创建控制台应用,添加所需的 DLL 和项目引用,然后按照 “添加调试对象”端数据对象中所述的步骤作。 有关 ASP.NET 核心方案,请参阅 .NET 5.0+ 的特殊调试器端注意事项

现在,必须添加必要的引用,以便 MyTestConsole 可以调用 MyFirstVisualizer。

添加对 MyTestConsole 的必要引用

  1. 解决方案资源管理器中,右键单击 MyTestConsole 并选择快捷菜单上的 “添加引用 ”。

  2. 在“ 添加引用 ”对话框中,打开 “浏览 ”选项卡,然后选择Microsoft.VisualStudio.DebuggerVisualizers.DLL。

  3. 选择“确定”

  4. 右键单击 MyTestConsole ,然后再次选择 “添加引用 ”。

  5. 在“ 添加引用 ”对话框中,打开“ 项目 ”选项卡,然后选择“MyFirstVisualizer”。

  6. 选择“确定”

现在,添加代码以完成测试工具。

将代码添加到 MyTestConsole

  1. 解决方案资源管理器中,右键单击Program.cs并选择快捷菜单上的 “重命名 ”。

  2. 将名称从Program.cs编辑为更有意义的内容,例如TestConsole.cs。

    注释

    Visual Studio 会自动更改TestConsole.cs中的类声明以匹配新文件名。

  3. 在TestConsole.cs中,将以下代码添加到 using 指令:

    using MyFirstVisualizer;
    
  4. 在方法 Main中,添加以下代码:

    String myString = "Hello, World";
    DebuggerSide.TestShowVisualizer(myString);
    

现在,你已准备好测试第一个可视化工具。

测试可视化工具

  1. 解决方案资源管理器中,右键单击 MyTestConsole ,然后选择快捷菜单上的 “设置为启动项目 ”。

  2. “调试 ”菜单上,选择“ 开始”。

    控制台应用程序启动后,可视化工具会显示字符串“Hello, World”。

祝贺。 你已生成并测试了第一个可视化工具!

如果要在 Visual Studio 中使用可视化器,而不仅仅是从测试框架调用它,则必须安装它。 有关详细信息,请参阅 如何:安装可视化工具

添加调试对象端数据对象

在本部分中,你将从 System.String 数据对象切换到自定义数据对象。

  1. 在解决方案资源管理器中,右键单击解决方案,选择 “添加”,然后选择“ 新建项目”。 在语言下拉列表中,选择 C#。 在搜索框中,键入 类库,然后选择 类库(.NET Framework) 或用于 .NET Standard 的 类库

    注释

    如果使用 .NET Framework 测试控制台应用,请确保创建 .NET Framework 类库项目。

  2. 选择“下一步”。 在出现的对话框中,键入名称 MyDataObject,然后选择“ 创建”。

  3. (仅限 .NET Standard 类库)在解决方案资源管理器中,右键单击项目,然后选择 “编辑项目文件”。 将 <TargetFramework> 值更改为 netstandard2.0.

    <TargetFramework>netstandard2.0</TargetFramework>
    
  4. 在命名空间中 MyDataObject ,将默认代码替换为以下代码。

    [Serializable] 
    public class CustomDataObject
    {
       public CustomDataObject()
       {
          this.MyData = "MyTestData";
       }
       public string MyData { get; set; }
    }
    

    对于只读可视化工具(如此示例中),不需要实现 VisualizerObjectSource 的方法。

    接下来,更新 MyFirstVisualizer 项目以使用新的数据对象。

  5. 在 MyFirstVisualizer 项目下的解决方案资源管理器中,右键单击 “引用 ”节点,然后选择“ 添加引用”。

  6. “项目”下,选择 MyDataObject 项目。

  7. 在DebuggerSide.cs的属性代码中,更新目标值,更改为 System.StringMyDataObject.CustomDataObject.

    Target = typeof(MyDataObject.CustomDataObject),
    
  8. 在 MyFirstVisualizer 项目中,将方法的代码 Show 替换为以下代码。

    var data = objectProvider.GetObject() as MyDataObject.CustomDataObject;
    
    // You can replace displayForm with your own custom Form or Control.  
    Form displayForm = new Form();
    displayForm.Text = data.MyData;
    windowService.ShowDialog(displayForm);
    

    前面的代码使用数据对象的属性,在窗体标题中呈现。

    接下来,更新控制台应用以使用自定义数据对象。

  9. 在 MyTestConsole 项目下的“解决方案资源管理器”中,右键单击 “引用 ”或“ 依赖项 ”节点,然后添加项目引用 MyDataObject

  10. 在Program.cs中,将方法中的 Main 代码替换为以下代码。

    // String myString = "Hello, World";
    CustomDataObject customDataObject = new CustomDataObject();
    
    DebuggerSide.TestShowVisualizer(customDataObject);
    
  11. (.NET 控制台应用)将对 TestShowVisualizer 的调用括在 try-catch 语句中,因为不支持测试驱动。

    try
    {
          DebuggerSide.TestShowVisualizer(customDataObject);
    }
    catch (Exception) {
    }
    

    控制台应用需要运行时引用到可视化器。 可以通过保留前面的代码而不是将其注释掉来保持引用。

  12. 对于 .NET Framework 控制台应用,可以运行测试工具(按 F5),也可以按照 “如何:安装可视化工具”中的说明进行作。

    如果使用测试工具运行应用,该应用会显示 Windows 窗体。

  13. 对于 .NET 控制台应用程序,请将 MyFirstVisualizer.dllMyDataObject.dll 复制到 如何:安装可视化器 中所述的文件夹。

  14. 安装可视化工具后,设置断点,运行控制台应用,并将鼠标悬停在上 customDataObject。 如果一切设置正确,应会看到放大镜图标 可视化工具Icon

    可视化工具放大镜图标。

    从放大镜中选择 MyFirstVisualizer 时,会看到标题中带有数据对象文本的窗体。

    显示 Windows 窗体的可视化工具