Compartilhar via


Visualizadores de dados personalizados para o depurador do Visual Studio (.NET)

Importante

A partir do Visual Studio 2022 versão 17.9, os visualizadores agora podem ser escritos no .NET 6.0+ que são executados fora do processo usando o novo modelo VisualStudio.Extensibility. Para extensões criadas usando o novo modelo, consulte a documentação no Criar visualizadores de depurador do Visual Studio. Se você precisar dar suporte a versões mais antigas do Visual Studio ou quiser enviar seus visualizadores personalizados como parte de uma DLL de biblioteca, use as informações neste artigo, que se aplicam apenas ao modelo mais antigo de desenvolvimento de extensão (VSSDK).

Um visualizador faz parte da interface do usuário do depurador do Visual Studio que exibe uma variável ou objeto de maneira apropriada ao seu tipo de dados. Por exemplo, um visualizador de bitmap interpreta uma estrutura de bitmap e exibe o gráfico que ele representa. Alguns visualizadores permitem modificar, bem como exibir os dados. No depurador, um visualizador é representado por um ícone de lupa VisualizerIcon. Você pode selecionar o ícone em um DataTip, na janela de Watch do depurador ou na caixa de diálogo QuickWatch e, em seguida, selecionar o visualizador apropriado para o objeto correspondente.

Além dos visualizadores internos padrão, mais visualizadores podem estar disponíveis para download da Microsoft, de terceiros e da comunidade. Você também pode escrever seus próprios visualizadores e instalá-los no depurador do Visual Studio.

Este artigo fornece uma visão geral de alto nível da criação do visualizador. Para obter instruções detalhadas, consulte os seguintes artigos em vez disso:

Observação

Não há suporte para visualizadores personalizados para aplicativos UWP (Plataforma Universal do Windows) e Windows 8.x.

Visão geral

Você pode escrever um visualizador personalizado para um objeto de qualquer classe gerenciada, exceto por Object e Array.

A arquitetura de um visualizador de depurador tem duas partes:

  • O lado do depurador é executado no depurador do Visual Studio, cria e exibe a interface do usuário do visualizador.

    Como o Visual Studio é executado no Runtime do .NET Framework, esse componente precisa ser gravado para o .NET Framework. Por esse motivo, não é possível gravá-lo para o .NET Core.

  • O lado de depuração é executado dentro do processo em que o Visual Studio está depurando (o depurador). O objeto de dados a ser visualizado (por exemplo, um objeto String) existe no processo do debuggee. O lado de depuração envia o objeto para o lado do depurador, que o exibe na interface do usuário que você cria.

    O runtime para o qual você cria esse componente deve corresponder ao em que o processo de depuração será executado, ou seja, o .NET Framework ou o .NET Core.

O lado do depurador recebe o objeto de dados de um provedor de objetos que implementa a IVisualizerObjectProvider interface. O lado do debug transmite o objeto através da origem do objeto, que é derivada de VisualizerObjectSource.

O provedor de objetos também pode enviar dados de volta para a fonte do objeto, o que permite que você escreva um visualizador que possa editar dados. Sobrescreva o provedor de objetos para interagir com o avaliador de expressões e a fonte do objeto.

O lado do debugado e o lado do depurador se comunicam entre si por meio de métodos Stream que serializam um objeto de dados em um Stream e desserializam o Stream de volta em um objeto de dados.

Você pode escrever um visualizador para um tipo genérico somente se o tipo for um tipo aberto. Essa restrição é a mesma que a restrição ao usar o DebuggerTypeProxy atributo. Para obter detalhes, consulte Usar o atributo DebuggerTypeProxy.

Visualizadores personalizados podem ter considerações de segurança. Confira as considerações de segurança do Visualizador.

Criar a interface do usuário do lado do depurador

Para criar a interface do usuário do visualizador no lado do depurador, crie uma classe que herda de DialogDebuggerVisualizer e substitua o método Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show para exibir a interface. Você pode usar IDialogVisualizerService para exibir formulários, caixas de diálogo e controles do Windows no visualizador.

  1. Use IVisualizerObjectProvider métodos para obter o objeto visualizado no lado do depurador.

  2. Criar uma classe que herda de DialogDebuggerVisualizer.

Observação

Devido aos problemas de segurança descritos na seção abaixo, a partir da versão 17.11 do Visual Studio 2022, os visualizadores não poderão especificar a política do formatador no construtor da classe base. De agora em diante, os visualizadores só podem usar a serialização JSON para se comunicar entre o depurador e os componentes do lado de depuração .

  1. Sobrescreva o Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show método para exibir sua interface. Use IDialogVisualizerService métodos para exibir formulários, caixas de diálogo e controles do Windows em sua interface.

  2. Aplicar DebuggerVisualizerAttribute, dando a ele o visualizador para exibir (DialogDebuggerVisualizer).

Considerações especiais do lado do depurador para .NET 5.0+

Os Visualizadores Personalizados transferem dados entre os lados depurado e depurador por meio da serialização binária usando a classe BinaryFormatter por padrão. No entanto, esse tipo de serialização está sendo reduzido no .NET 5 e posterior devido a preocupações com a segurança em relação às vulnerabilidades infixáveis . Além disso, ele foi marcado como completamente obsoleto no ASP.NET Core 5 e seu uso será gerado conforme descrito na Documentação do ASP.NET Core. Esta seção descreve as etapas que você deve executar para garantir que o visualizador ainda tenha suporte neste cenário.

  • Por motivos de compatibilidade, o Show método que foi substituído na seção anterior ainda usa um IVisualizerObjectProvider. No entanto, a partir do Visual Studio 2019 versão 16.10, ele é realmente do tipo IVisualizerObjectProvider3. Por esse motivo, faça o casting do objectProvider objeto para a interface atualizada.

  • Ao enviar objetos, como comandos ou dados, para o lado do depurado, use o método IVisualizerObjectProvider2.Serialize para passá-lo a um fluxo. Ele determinará o melhor formato de serialização a ser usado com base no tempo de execução do processo do depurado. Em seguida, passe o fluxo para o IVisualizerObjectProvider2.TransferData método.

  • Se o componente do visualizador do lado de depuração precisar retornar qualquer coisa para o lado do depurador, ele estará localizado no Stream objeto retornado pelo TransferData método. Use o método IVisualizerObjectProvider2.GetDeserializableObjectFrom para obter uma instância IDeserializableObject dela e processá-la conforme necessário; ou use DeserializeFromJson se for um tipo que você sabe desserializar.

Consulte a seção considerações especiais do lado do debuggee para .NET 5.0+ para saber quais outras alterações são necessárias no lado do debuggee quando não há suporte para o uso da Serialização Binária.

Observação

Se você quiser obter mais informações sobre o problema, consulte o guia de segurança do BinaryFormatter.

Criar a origem do objeto visualizador para o lado de depuração

No código do lado do depurador, edite o DebuggerVisualizerAttribute, atribuindo o tipo a ser visualizado (a fonte do objeto no lado a ser depurado) (VisualizerObjectSource). A Target propriedade define a origem do objeto. Se você omitir a origem do objeto, o visualizador usará uma fonte de objeto padrão.

O código do lado de depuração contém a fonte do objeto que é visualizada. O objeto de dados pode substituir métodos de VisualizerObjectSource. Uma DLL do lado do debug é necessária se você quiser criar um visualizador independente.

No código do lado de depuração:

  • Para permitir que o visualizador edite objetos de dados, o objeto fonte deve herdar de VisualizerObjectSource e sobrescrever os métodos TransferData ou CreateReplacementObject.

  • Se você precisar dar suporte ao direcionamento múltiplo em seu visualizador, poderá usar os seguintes TFMs (Monikers da Estrutura de Destino) no arquivo do projeto no lado do depurador.

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

    Esses são os únicos TFMs com suporte.

Considerações especiais do lado de depuração para .NET 5.0+

Importante

Etapas adicionais podem ser necessárias para que um visualizador funcione a partir do .NET 5.0 devido a preocupações de segurança em relação ao método de serialização binária subjacente usado por padrão. Leia esta seção antes de continuar.

  • Se o visualizador implementar o método TransferData, use o método GetDeserializableObject recém-adicionado que está disponível na versão mais recente do VisualizerObjectSource. O IDeserializableObject retorno ajuda a determinar o formato de serialização do objeto (binário ou JSON) e a desserializar o objeto subjacente para que ele possa ser usado.

  • Se o lado do depurado retornar dados para o lado do depurador como parte da chamada , serialize a resposta no fluxo do lado do depurador usando o método .