Niestandardowe wizualizatory danych dla debugera programu Visual Studio (.NET)

Wizualizator jest częścią interfejsu użytkownika debugera programu Visual Studio, który wyświetla zmienną lub obiekt w sposób odpowiedni dla jego typu danych. Na przykład wizualizator mapy bitowej interpretuje strukturę mapy bitowej i wyświetla grafikę, która reprezentuje. Niektóre wizualizatory umożliwiają modyfikowanie, a także wyświetlanie danych. W debugerze wizualizator jest reprezentowany przez ikonę VisualizerIconlupy . Możesz wybrać ikonę w oknie DataTip, debugger Watch lub QuickWatch , a następnie wybrać odpowiedni wizualizator dla odpowiedniego obiektu.

Oprócz standardowych wbudowanych wizualizatorów więcej wizualizatorów może być dostępnych do pobrania z firmy Microsoft, innych firm i społeczności. Możesz również napisać własne wizualizatory i zainstalować je w debugerze programu Visual Studio.

Ten artykuł zawiera ogólne omówienie tworzenia wizualizatora. Aby uzyskać szczegółowe instrukcje, zobacz następujące artykuły:

Uwaga

Niestandardowe wizualizatory nie są obsługiwane w przypadku aplikacji platforma uniwersalna systemu Windows (UWP) i Windows 8.x.

Omówienie

Można napisać niestandardowy wizualizator dla obiektu dowolnej klasy zarządzanej z wyjątkiem i ObjectArray.

Architektura wizualizatora debugera ma dwie części:

  • Strona debugera jest uruchamiana w debugerze programu Visual Studio i tworzy i wyświetla interfejs użytkownika wizualizatora.

    Ponieważ program Visual Studio jest wykonywany w środowisku uruchomieniowym programu .NET Framework, ten składnik musi być napisany dla programu .NET Framework. Z tego powodu nie można zapisać go dla platformy .NET Core.

  • Strona debugowania jest uruchamiana w ramach procesu debugowania programu Visual Studio ( debuggee). Obiekt danych do wizualizacji (na przykład obiekt String) istnieje w procesie debuggee. Strona debugowania wysyła obiekt do strony debugera, który wyświetla go w utworzonym interfejsie użytkownika.

    Środowisko uruchomieniowe, dla którego kompilujesz ten składnik, powinno być zgodne z tym, w którym zostanie uruchomiony proces debugowania, czyli .NET Framework lub .NET Core.

Strona debugera odbiera obiekt danych od dostawcy obiektów, który implementuje IVisualizerObjectProvider interfejs. Strona debugowania wysyła obiekt za pośrednictwem źródła obiektu, które pochodzi z VisualizerObjectSourceelementu .

Dostawca obiektów może również wysyłać dane z powrotem do źródła obiektów, co umożliwia napisanie wizualizatora, który może edytować dane. Zastąpisz dostawcę obiektów, aby komunikować się z ewaluatorem wyrażeń i źródłem obiektu.

Strona debugowania i strona debugera komunikują się ze sobą za pośrednictwem Stream metod, które serializują obiekt danych w Stream obiekt danych i deserializują Stream z powrotem do obiektu danych.

Wizualizator dla typu ogólnego można napisać tylko wtedy, gdy typ jest typem otwartym. To ograniczenie jest takie samo jak ograniczenie podczas używania atrybutu DebuggerTypeProxy . Aby uzyskać szczegółowe informacje, zobacz Use the DebuggerTypeProxy attribute (Używanie atrybutu DebuggerTypeProxy).

Niestandardowe wizualizatory mogą mieć zagadnienia dotyczące zabezpieczeń. Zobacz Zagadnienia dotyczące zabezpieczeń wizualizatora.

Tworzenie interfejsu użytkownika po stronie debugera

Aby utworzyć interfejs użytkownika wizualizatora po stronie debugera, należy utworzyć klasę dziedziczą po DialogDebuggerVisualizermetodzie i zastąpić Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show metodę w celu wyświetlenia interfejsu. Za pomocą IDialogVisualizerService funkcji wizualizatora można wyświetlać formularze, okna dialogowe i kontrolki systemu Windows.

  1. Użyj IVisualizerObjectProvider metod , aby uzyskać wizualizowany obiekt po stronie debugera.

  2. Utwórz klasę dziedziczą z klasy DialogDebuggerVisualizer.

  3. Zastąpij metodę Microsoft.VisualStudio.DebuggerVisualizers.DialogDebuggerVisualizer.Show w celu wyświetlenia interfejsu. Użyj IDialogVisualizerService metod do wyświetlania formularzy, okien dialogowych i kontrolek systemu Windows w interfejsie.

  4. Zastosuj DebuggerVisualizerAttributeelement , nadając mu wizualizator do wyświetlania (DialogDebuggerVisualizer).

Specjalne zagadnienia dotyczące strony debugera dla platformy .NET 5.0 lub nowszej

Niestandardowe wizualizatory przesyłają dane między debugerem a debugerem za pomocą serializacji binarnej BinaryFormatter przy użyciu klasy domyślnie. Jednak ten rodzaj serializacji jest ograniczany na platformie .NET 5 i nowszych ze względu na obawy dotyczące zabezpieczeń dotyczące niefiksowanych luk w zabezpieczeniach. Ponadto został on oznaczony jako całkowicie przestarzały w ASP.NET Core 5, a jego użycie zostanie zgłoszony zgodnie z opisem w dokumentacji ASP.NET Core. W tej sekcji opisano kroki, które należy wykonać, aby upewnić się, że wizualizator jest nadal obsługiwany w tym scenariuszu.

  • Ze względów Show zgodności metoda, która została zastąpiona w poprzedniej sekcji, nadal przyjmuje metodę IVisualizerObjectProvider. Jednak począwszy od programu Visual Studio 2019 w wersji 16.10, jest to faktycznie typ IVisualizerObjectProvider2. Z tego powodu oddaj objectProvider obiekt do zaktualizowanego interfejsu.

  • Podczas wysyłania obiektów, takich jak polecenia lub dane, po stronie debugowania użyj IVisualizerObjectProvider2.Serialize metody , aby przekazać ją do strumienia, określi najlepszy format serializacji do użycia na podstawie środowiska uruchomieniowego procesu debuggee . Następnie przekaż strumień do IVisualizerObjectProvider2.TransferData metody .

  • Jeśli składnik wizualizatora po stronie debugowania musi zwrócić wszystko po stronie debugera, zostanie on umieszczony w Stream obiekcie zwróconym przez metodęTransferData. IVisualizerObjectProvider2.GetDeserializableObjectFrom Użyj metody , aby pobrać z IDeserializableObject niego wystąpienie i przetworzyć je zgodnie z potrzebami.

Zapoznaj się z sekcją Specjalne zagadnienia po stronie debugowania dla platformy .NET 5.0+ , aby dowiedzieć się, jakie inne zmiany są wymagane po stronie debugowania w przypadku korzystania z serializacji binarnej nie jest obsługiwane.

Uwaga

Jeśli chcesz uzyskać więcej informacji na temat problemu, zobacz Przewodnik zabezpieczeń BinaryFormatter.

Tworzenie źródła obiektu wizualizatora dla strony debugowania

W kodzie bocznym debugera zmodyfikuj DebuggerVisualizerAttributeelement , nadając mu typ do wizualizacji (źródło obiektu po stronie debugowania) (VisualizerObjectSource). Właściwość Target ustawia źródło obiektu. Jeśli pominięto źródło obiektu, wizualizator użyje domyślnego źródła obiektu.

Kod boczny debuggee zawiera źródło obiektu, które jest wizualizowane. Obiekt danych może zastąpić metody VisualizerObjectSource. Biblioteka DLL po stronie debugowania jest niezbędna, jeśli chcesz utworzyć autonomiczny wizualizator.

W kodzie po stronie debugowania:

  • Aby umożliwić wizualizatorowi edytowanie obiektów danych, źródło obiektu musi dziedziczyć VisualizerObjectSource i zastępować TransferData metody lub CreateReplacementObject .

  • Jeśli musisz obsługiwać wielowersyjność w wizualizatorze, możesz użyć następującego elementu Target Framework Monikers (TFMs) w pliku projektu po stronie debugowania.

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

    Są to jedyne obsługiwane maszyny TFM.

Specjalne zagadnienia dotyczące strony debugowania dla platformy .NET 5.0 lub nowszej

Ważne

Aby wizualizator działał w środowisku .NET 5.0, może być konieczne wykonanie dodatkowych kroków ze względu na obawy dotyczące zabezpieczeń podstawowej metody serializacji binarnej używanej domyślnie. Przed kontynuowaniem przeczytaj tę sekcję .

  • Jeśli wizualizator implementuje metodę TransferData , użyj nowo dodanej GetDeserializableObject metody, która jest dostępna w najnowszej wersji programu VisualizerObjectSource. Funkcja IDeserializableObject zwracana ułatwia określenie formatu serializacji obiektu (binarnego lub JSON) oraz deserializacji bazowego obiektu w taki sposób, aby mógł być używany.

  • Jeśli strona debugowania zwraca dane po stronie debugera w ramach TransferData wywołania, serializuj odpowiedź na strumień po stronie debugera za pośrednictwem Serialize metody .