Пользовательские визуализаторы данных для отладчика Visual Studio (.NET)

Визуализатор — это компонент пользовательского интерфейса отладчика Visual Studio, который отображает переменную или объект способом, подходящим для этого типа данных. Например, визуализатор растрового изображения интерпретирует структуру растрового изображения и отображает рисунок, который он представляет. Некоторые визуализаторы позволяют не только просматривать, но и редактировать данные. В отладчике визуализатор представлен значком Визуализатор Иконс увеличением стекла. Можно выбрать значок в DataTip, окне Контрольные значения отладчика или диалоговом окне Быстрая проверка, а затем выбрать подходящий визуализатор для соответствующего объекта.

Помимо стандартных встроенных визуализаторов, для скачивания из Корпорации Майкрософт, сторонних производителей и сообщества могут быть доступны дополнительные визуализаторы. Кроме того, вы можете создавать собственные визуализаторы и устанавливать их в отладчик Visual Studio.

В этой статье представлен общий обзор создания визуализатора. Подробные инструкции см. в следующих статьях:

Примечание.

Пользовательские визуализаторы не поддерживаются для приложений универсальная платформа Windows (UWP) и Windows 8.x.

Обзор

Пользовательский визуализатор можно создать для объекта любого управляемого класса, за исключением Object и Array.

Архитектура визуализатора отладчика состоит из двух частей:

  • Сторона отладчика выполняется в отладчике Visual Studio и создает и отображает пользовательский интерфейс визуализатора.

    Так как Visual Studio выполняется в среде выполнения .NET Framework, этот компонент должен быть написан для .NET Framework. Поэтому его нельзя написать для .NET Core.

  • Сторона отлаживаемого кода — код, который выполняется внутри процесса, отлаживаемого в Visual Studio (отлаживаемая программа). Объект данных для визуализации (например, строковый объект) существует в отлаживаемом процессе. Сторона отлаживаемой программы отправляет объект на сторону отладчика, где он отображается в созданном пользовательском интерфейсе.

    Среда выполнения, для которой создается этот компонент, должна соответствовать той, в которой будет выполняться отлаживаемый процесс. Это может быть .NET Framework или .NET Core.

Сторона отладчика получает объект данных для визуализации от поставщика объектов. В поставщике объектов реализуется интерфейс IVisualizerObjectProvider. Сторона отлаживаемой программы отправляет объект, используя источник объекта, который является производным от VisualizerObjectSource.

Поставщик объектов может также отправлять данные обратно к источнику объекта, что позволяет создавать визуализаторы, которые могут изменять данные. Поставщик объектов может быть переопределен, чтобы контактировать с вычислителем выражений и, следовательно, с источником объектов.

Сторона отлаживаемой программы и сторона отладчика взаимодействуют друг с другом с помощью методов Stream, выполняющих сериализацию объекта данных в Stream и десериализацию Stream обратно в объект данных.

Можно написать визуализатор для универсального типа, только если тип является открытым. Ограничения накладываются те же, что и при использовании атрибута DebuggerTypeProxy. Дополнительные сведения см. в статье об использовании атрибута DebuggerTypeProxy.

Пользовательские визуализаторы могут учитывать вопросы безопасности. См. статью Вопросы безопасности визуализатора.

Создание пользовательского интерфейса отладчика

Чтобы создать пользовательский интерфейс визуализатора на стороне отладчика, необходимо создать класс, который наследует DialogDebuggerVisualizer, и переопределить метод Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show для отображения интерфейса. Для отображения в визуализаторе форм, диалоговых окон и элементов управления Windows можно использовать интерфейс IDialogVisualizerService.

  1. Используйте методы IVisualizerObjectProvider для получения визуализированного объекта на стороне отладчика.

  2. Создайте класс, который наследует от DialogDebuggerVisualizer.

  3. Переопределите метод Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show для отображения интерфейса. Используйте методы IDialogVisualizerService для отображения в интерфейсе форм, диалоговых окон и элементов управления Windows.

  4. Примените DebuggerVisualizerAttribute, задавая ему визуализатор для отображения (DialogDebuggerVisualizer).

Особые рекомендации в отношении отладчика для .NET 5.0+

По умолчанию пользовательские визуализаторы передают данные между отлаживаемым объектом и отладчиком с помощью двоичной сериализации, реализуемой классом BinaryFormatter. Однако такой тип сериализации не поддерживается в .NET 5 и более поздних версиях из-за проблем безопасности, связанных с неустранимыми уязвимостями. Более того, он был помечен как полностью устаревший в ASP.NET Core 5 и в скором времени перестанет использоваться, как описано в документации по ASP.NET Core. В этом разделе описаны действия, которые необходимо выполнить, чтобы обеспечить поддержку визуализатора в данном сценарии.

  • Для обеспечения совместимости метод Show, который был переопределен в предыдущем разделе, по-прежнему включен в IVisualizerObjectProvider. Однако начиная с Visual Studio 2019 версии 16.10, он имеет тип IVisualizerObjectProvider2. Поэтому нужно привести объект objectProvider к обновленному интерфейсу.

  • При отправке объектов, таких как команды или данные, отлаживаемому объекту используйте метод IVisualizerObjectProvider2.Serialize для передачи этих данных в поток. Этот метод определит оптимальный формат сериализации в зависимости от среды выполнения отлаживаемого процесса. Затем передайте поток в метод IVisualizerObjectProvider2.TransferData.

  • Если компонент визуализатора на стороне отлаживаемого объекта должен вернуть какие-либо данные отладчику, эти данные будут расположены в объекте Stream, возвращенном методом TransferData. Используйте метод IVisualizerObjectProvider2.GetDeserializableObjectFrom, чтобы получить от него экземпляр IDeserializableObject и обработать его должным образом.

В разделе Особые рекомендации в отношении отлаживаемого объекта для .NET 5.0+ ознакомьтесь со сведениями о других изменениях, которые требуются для отлаживаемого объекта, если двоичная сериализация не поддерживается.

Примечание.

Дополнительные сведения об этой проблеме см. в статье Руководство по безопасности BinaryFormatter.

Создание источника объекта визуализатора для стороны отладчика

В коде на стороне отлаживаемого объекта измените DebuggerVisualizerAttribute, предоставив тип для визуализации (источник объекта на стороне отлаживаемого объекта) (VisualizerObjectSource). Свойство Target задает источник объекта. Если источник объекта не задан, визуализатор будет использовать источник объекта, заданный по умолчанию.

Код отлаживаемого объекта содержит источник объекта для визуализации. Объект данных может переопределять методы VisualizerObjectSource. Библиотека DLL на стороне отлаживаемого объекта требуется для создания автономного визуализатора.

В коде на стороне отлаживаемого объекта:

  • Чтобы визуализатор редактировал объекты данных, источник объекта должен наследоваться от VisualizerObjectSource и переопределять TransferData методы или CreateReplacementObject методы.

  • Если нужно включить поддержку многоплатформенного нацеливания в визуализаторе, можно использовать следующие моникеры целевой платформы (TFM) в файле проекта на стороне отлаживаемого объекта.

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

    Это единственные поддерживаемые TFM.

Особые рекомендации в отношении отлаживаемого объекта для .NET 5.0+

Внимание

Чтобы обеспечить работу визуализатора начиная с .NET 5.0, возможно, потребуется выполнить дополнительные действия из-за проблем безопасности с базовым методом двоичной сериализации, который используется по умолчанию. Прежде чем продолжить, ознакомьтесь с этим разделом.

  • Если визуализатор реализует метод TransferData, используйте новый метод GetDeserializableObject, доступный в последней версии VisualizerObjectSource. Возвращаемый IDeserializableObject объект помогает определить формат сериализации объекта (двоичный или JSON) и десериализировать базовый объект, чтобы его можно было использовать.

  • Если отлаживаемый объект возвращает данные отладчику в рамках вызова TransferData, сериализуйте ответ в поток на стороне отладчика с помощью метода Serialize.