Visual Studio デバッガー用のカスタム データ ビジュアライザー (.NET)

"ビジュアライザー" は、Visual Studio デバッガーのユーザー インターフェイスの一部で、データ型に適した方法で変数またはオブジェクトが表示されます。 たとえば、ビットマップ ビジュアライザーでは、ビットマップ構造が解釈され、それが表すグラフィックが表示されます。 一部のビジュアライザーでは、データを表示するだけでなく、変更することもできます。 デバッガーでは、ビジュアライザーは拡大鏡アイコン VisualizerIcon で表されます。 このアイコンを [データヒント] 、デバッガーの [ウォッチ] ウィンドウ、または [クイックウォッチ] ダイアログ ボックスで選択し、対応するオブジェクトに適したビジュアライザーを選択することができます。

標準のビルトイン ビジュアライザーに加えて、Microsoft、サード パーティ、コミュニティから追加のビジュアライザーをダウンロードできる場合があります。 また、独自のビジュアライザーを作成して、Visual Studio デバッガーにインストールすることもできます。

この記事では、ビジュアライザー作成の概要について説明します。 詳しい手順については、代わりに次の記事をご覧ください。

Note

カスタム ビジュアライザーは、ユニバーサル Windows プラットフォーム (UWP) および Windows 8.x アプリではサポートされていません。

概要

Object および Array を除く任意のマネージド クラスのオブジェクトのカスタム ビジュアライザーを記述できます。

デバッガー ビジュアライザーのアーキテクチャには、次の 2 つの部分があります。

  • "デバッガー側" - 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 メソッドをオーバーライドしてインターフェイスを表示する必要があります。 IDialogVisualizerService を使用すると、ビジュアライザーで Windows フォーム、ダイアログ、コントロールを表示できます。

  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 メソッドに渡します。

  • "デバッグ対象側" のビジュアライザー コンポーネントが "デバッガー側" に何かを返す必要がある場合、それは TransferData メソッドによって返される Stream オブジェクトに配置されます。 IVisualizerObjectProvider2.GetDeserializableObjectFrom メソッドを使用してそこから IDeserializableObject インスタンスを取得し、必要に応じて処理します。

バイナリ シリアル化の使用がサポートされていない場合に、"デバッグ対象側" で必要なその他の変更については、「.NET 5.0 以上のデバッグユーザー側の特別な考慮事項」セクションを参照してください。

Note

この問題の詳細については、「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 メソッドが実装される場合は、最新バージョンの VisualizerObjectSource で使用できる新しく追加された GetDeserializableObject メソッドを使用します。 これによって返される IDeserializableObject により、オブジェクトのシリアル化形式 (バイナリまたは JSON) を判定し、使用できるようにするために基になるオブジェクトを逆シリアル化できます。

  • "デバッグ対象側" によって TransferData 呼び出しの一部として "デバッガー側" にデータが返された場合、Serialize メソッドを使用して応答を "デバッガー側" のストリームにシリアル化します。