Authoring Visualizers Article

January 22, 2008

I have posted my Authoring Visualizers Sample on Code Project.  You can read the article at http://www.codeproject.com/KB/vb/AuthoringVisualizers.aspx.

Just a grain of sand on the worlds beaches.


Sample Series – Authoring Debugger Visualizers

January 20, 2008

The purpose of the Sample Series is to provide concise code solutions for specific programming tasks. This sample provides a brief description of visualizers, how to author them, the solution and full source code with a test bench program.

Visual Studio Debugger Visualizers are a great addition to the developers debugging toolbox.  Their purpose is to provide a custom view of data during a debugging session.  Visualizers can be as simple as a string or dataset visualizer or as complex as Mole.

The simple visualizer that we will develop in this sample, visualizes strings and allows the string to be replaced during the visualizer session.

We will also cover how to debug debugger visualizers.

I have recorded three videos that accompany this sample.  One on authoring debugger visualizers and two on debugging debugger visualizers.  I suggest that you view the three videos as an introduction and then read this material.  You can view the videos using the two links below.

silverlight_logo_small.gif

New SilverLight Videos – These Are The Bomb!

You must have Silverlight 1.0 installed on your computer. Takes about a minute or so.

When you click on the below links, your browser will open and display the video. The player will resize as you resize your browser. You can also press the Full Screen button and the video will go full screen.

movie3 Authoring Debugger Visualizers SilverLight Video

movie3 Debugging Debugger Visualizers SilverLight Video

movie3 Debugging Debugger Visualizers Two SilverLight Video

Source Code Project Download

Authoring Visualizers Source Code Download

Launching A Visualizer During Debugging Session

Visualizers are very easy to start. When debugging and at a breakpoint, hover your mouse over the object you want to visualize. If a visualizer is installed on your system which can visualize that object Type, the little magnifying glass will appear in the datatip. You can also start a visualizer from the Watch Window.

You can click the magnifying glass to open the default visualizer for that object Type. Or you can click the down arrow and select a visualizer to use. The check mark indicates the last visualizer used for the selected object type.

usingdatatip

Using the data tip.

usingwatchwindow

Using the watch window.  Notice the magnifying glass in the Value column.

Visualizers 101

The first article I read was Creating Debugger Visualizers with Visual Studio 2005 by Julia Lerman. She does an outstanding job of getting you started. Another good starting point is the MSDN Visualizer Architecture article. Also there many articles on Code Project and the Internet covering visualizers. Basically there are four partners, running in two processes, that work together in the visualizer world.

Debugger Side
  • Visual Studio Debugger – provides UI to select a visualizer to open.
  • Visualizer UI – runs within the VS debugger process.
Debuggee Side
  • Your Program – the program you are debugging. This process has the visual tree we want to visualize.
  • Visualizer Object Source – runs within your program’s process.

Visual Studio plays the middle man handling communications between the two processes. The bottom line is, your visualizer UI has no data, until it makes a request to the VisualizerObjectSource. All data which moves between the two processes must be serialized. This is important to remember when building your data structures. Both sides of the conversation are active throughout the visualizer’s life. This allows your UI to make repeated requests to the data object whenever it needs more data to display. The communications plumbing Microsoft provided is incredibly fast, even with all the serialization and deserialization going on.

If you have to move large amounts of data like we did in Mole, consider using .NET custom serialization for your data classes rather than relying on the default .NET serialization.

Visualizer Project

If you are used to writing executables, this is going to blow your mind. Your visualizer complies into one class library .DLL, part of which runs in one process and the other part is running in the other process. The classes from the Debugger process communicate through Visual Studio to classes in the Debuggee process.

Managing The Visualizer Development Process

One decision you will need to make is how you want to manage getting the debugger visualizer build output into the correct directory for debugger visualizers.  You have many choices.  The easiest method, is to simply change the output directory for the visualizer project to one of the below directories.  You can also use the after build scripts to copy the file.  Or, you can manually copy the visualizer dll after each build.  Your choice, take your pick.  Just remember, before shipping your visualizer code, to put the output directory back to the default \bin directory.  This will help developers who are using your visualizer source code and reduce their confusion.

If you are developing on Vista and are running with Elevated Security enabled, you must install the visualizer in the following directory.

  • VS Install path\Common7\Packages\Debugger\Visualizers

All others copy the visualizer file to either:

  • My Documents\Visual Studio 2005\Visualizers {VS2005}
  • My Documents\Visual Studio 2008\Visualizers {VS2008}

If you are developing an ASP.NET debugger visualizer and you are running your ASP.NET web site under IIS, you must give the account that the ASP.NET web site is running under, Read and Read Execute permissions on the above directory you are using for your visualizer dll.

Sample Test Bench Application

SampleProgram

This is the UI for the frmTestStringVisualizer.cs file.

The solution has three projects.  One VB.NET test bench UI (AuthoringVisualizers.vbproj), one C# test bench UI (AuthorVisualizersThatWorks.csproj) and one Visualizer (SampleStringVisualizer.vbproj).

The reason for two UI projects is because when I started out writing the test bench application, I discovered that the VB.NET test bench application won’t allow the visualizer to replace the data.  I spent two hours trying to get this to work.  I even downloaded another visualizer, authored by another developer, just to test my VB.NET UI program, just in case my visualizer was not coded correctly.  It turns out that VB.NET WinForm applications will not allow the debugger visualizer to use the ReplaceData or ReplaceObject methods.  No exceptions are returned.  The data just does not get updated.  So, I wrote a C# WinForm application for this test project.

Lets have a look at the code in the test bench UI.

namespace AuthorVisualizersThatWorks
{ 

  public partial class frmTestStringVisualizer : Form
  { 

    public frmTestStringVisualizer()
    {
      InitializeComponent();
    } 

    private void btnVisualize_Click(object sender, EventArgs e)
    {
      string strTest = this.txtString.Text;
      // place your breakpoint on the next line
      this.txtString.Text = strTest;
    }
  }
}

This is the place where you’ll place your breakpoint and when debugging Visual Studio will pause here.  Then hold the mouse cursor over the strTest variable and launch the Sample String Visualizer.

SampleStringVisualier

<Assembly: System.Diagnostics.DebuggerVisualizer( _
  GetType(SampleStringVisualizer.StringVisualizer), _
  GetType( _
  SampleStringVisualizer.StringVisualizerObjectSource), _
  Target:=GetType(System.String), _
  Description:="Sample String Visualizer")>  


Public Class StringVisualizer
  Inherits DialogDebuggerVisualizer 

  Protected Overrides Sub Show(ByVal windowService _
    As _
    Microsoft.VisualStudio.DebuggerVisualizers.IDialogVisualizerService, _
    ByVal objectProvider As _
    Microsoft.VisualStudio.DebuggerVisualizers.IVisualizerObjectProvider)
     Using frm As New frmStringVisualizer
      frm.ObjectProvider = objectProvider
      frm.StringToVisualize = CType( _
        objectProvider.GetObject, String)
      windowService.ShowDialog(frm)
    End Using 

  End Sub 

End Class

The above code is the visualizer class.  There are two things that make a class a visualizer.  The DebuggerVisualizer attribute on the assembly and the class that derives from DialogDebuggerVisualizer.

There are four parameters we are passing in the constructor of the attribute.  The Type of the visualizer class, the Type of the visualizer object source class, the target Type and the description of the visualizer.  The description property value appears in the data tip of the visualizer in the Visual Studio debugger.

If you are not supplying your own visualizer object source, then use the default one supplied by Microsoft.  The name of that type is, “Microsoft.VisualStudio.DebuggerVisualizers.VisualizerObjectSource.”

This class is the entry point for the visualizer.  Visual Studio calls the Show method when the visualizer is started.  The Show method is where you can launch your visualizer UI and pass the required information to the UI.

If your visualizer does not need access to the methods of the IVisualizerObjectProvider, then you do not need to pass this class to the UI.  In the visualizer, I have decided to allow the visualizer to replace the text that is pass to it and I want that code to execute in the visualizer UI form, so I’m passing the IVisualizerObjectProvider instance to the form.

Notice that we are retrieving the object that was hovered over in the Visual Studio debugger when the visualizer was started.  We are accomplishing this by using the objectProvider.GetObject method and then casting the result of that call as a string.  The GetObject method is actually calling back to the debuggee side process, then serializing the target object and passing it to the debugger side as the result of the GetObject method.

Even in a very complex visualizer like Mole, the visualizer code here is very simple.  Most of heavy work takes place in the visualizer UI and the visualizer object source.

SampleStringVisualizer – StringVisualizerObjectSource

Imports Microsoft.VisualStudio.DebuggerVisualizers
Imports System.Runtime.Serialization.Formatters.Binary 

Public Class StringVisualizerObjectSource
  Inherits VisualizerObjectSource 

#Region " Declarations " 

  Private Shared _objBinaryFormatter As New _
    BinaryFormatter 

#End Region 

#Region " Overriden Methods " 

  Public Overrides Sub GetData(ByVal target As _
    Object, ByVal outgoingData As System.IO.Stream)
    StringVisualizerObjectSource.Serialize( _
      outgoingData, target) 

End Sub 

#End Region 

#Region " Helper Methods " 

  Public Shared Sub DebugVisualizer(ByVal obj As _
    Object) 

    Dim vdh As VisualizerDevelopmentHost = New _
      VisualizerDevelopmentHost(obj, GetType( _
      SampleStringVisualizer.StringVisualizer), _
      GetType( _
      SampleStringVisualizer.StringVisualizerObjectSource))
     vdh.ShowVisualizer() 

  End Sub 

  Public Overloads Shared Function Deserialize( _
    ByVal incomingData As System.IO.Stream) As Object
     Return _objBinaryFormatter.Deserialize( _
      incomingData) 

  End Function 

  Public Overloads Shared Sub Serialize(ByVal _
    serializationStream As System.IO.Stream, ByVal _
    target As Object)
     _objBinaryFormatter.Serialize( _
      serializationStream, target) 

  End Sub 

#End Region 

End Class

The above is the visualizer object source class.  The visualizer object source class must derive from VisualObjectSource.  There are several methods that the developer can override.  In the above code, we are only overriding the GetData method.  This very simple visualizer does not require a custom visualizer object source.  I’ve done this for instructional purposes only.

The purpose of the GetData method is to allow the visualizer developer to write custom code to package up the target object.  Remember this method is called when the debugger side calls the GetData method.  In the above example, we are simply serializing and returning the target object.

Each visualizer has different needs.  One requirement of visualizers is that the target object must be serializable.  However, you can get around this limitation by overriding the GetData method and repacking your target object into a serializable class object.

There are several helper methods in this class.  In fact, you can use this class as a template for your debugger visualizer object source classes.

The DebugVisualizer method is used to initiate debugging of the visualizer.  See the Debugging Visualizers section at the bottom of this article for an explanation.

The Deserialize and Serialize methods provide a common interface for the debugger and debuggee side code to perform these operations.

SampleStringVisualizer UI – frmStringVisualizer

SampleVisualizer

The above image shows what the visualizer looks like.  A label displays the number of characters in the string and a TextBox allows the developer to edit the string text.  If the string object can be replaced by the visualizer, the Replace Text Button will be enabled.  Lets have a look at the visualizer UI code.

Imports Microsoft.VisualStudio.DebuggerVisualizers 

Public Class frmStringVisualizer 

#Region " Declarations " 

  Private _objObjectProvider As _
    IVisualizerObjectProvider 

#End Region 

#Region " Properties " 

  Public Property ObjectProvider() As _
    IVisualizerObjectProvider
    Get
      Return _objObjectProvider
    End Get
    Set(ByVal Value As IVisualizerObjectProvider)
      _objObjectProvider = Value
    End Set
  End Property 

  Public Property StringToVisualize() As String
    Get
      Return Me.txtString.Text
    End Get
    Set(ByVal Value As String)
      Me.txtString.Text = Value
    End Set
  End Property 

#End Region 

#Region " Methods " 

  Private Sub btnClose_Click(ByVal sender As _
    System.Object, ByVal e As System.EventArgs) _
    Handles btnClose.Click
    Me.Close() 

  End Sub 

  Private Sub btnReplaceText_Click(ByVal sender As _
    System.Object, ByVal e As System.EventArgs) _
    Handles btnReplaceText.Click
    'There are two ways to replace data.  Take your choice.
    '
    '1.  use the ReplaceData Method
    Using ms As New System.IO.MemoryStream
      StringVisualizerObjectSource.Serialize( _
        ms, Me.StringToVisualize)
      ObjectProvider.ReplaceData(ms)
      ms.Close()
    End Using 
    '2.  use the ReplaceObject Method
    'ObjectProvider.ReplaceObject(Me.StringToVisualize)
    Me.Close() 

  End Sub 

  Private Sub frmStringVisualizer_Load(ByVal sender _
    As System.Object, ByVal e As System.EventArgs) _
    Handles MyBase.Load
         Me.btnReplaceText.Enabled = _
      Me.ObjectProvider.IsObjectReplaceable 

    If Me.btnReplaceText.Enabled Then
      Me.ToolTip1.SetToolTip(Me.btnReplaceText, _
        "Click to replace the original text with what you " & _         "have entered in the above textbox.") 

    Else
      Me.ToolTip1.SetToolTip(Me.btnReplaceText, _
        "The source object does not support replacement.")
    End If 

  End Sub 

  Private Sub txtString_TextChanged(ByVal sender As _
    Object, ByVal e As System.EventArgs) Handles _
    txtString.TextChanged
    Me.lblStringLength.Text = String.Format( _
      "{0} characters", _
      Me.txtString.Text.Trim.Length) 

  End Sub 

#End Region 

End Class

This code is self-explanatory for the most part.  The two properties provide a public interface for passing required data and the ObjectProvider instance.  These values as passed to the form in the StringVisualizer.Show method.

Have a look at the form load event handler, frmStringVisualizer_Load. The IVisualizerObjectProvider ObjectProvider exposes the IsObjectReplaceable property so developers can know in advance if the target object can be replaced. In the above code, I’m using the result of this property to either Enable or Disable the Replace Text button.

The btnReplaceText_Click event is the only code that needs some comments.  This event handler uses the ObjectProvider.ReplaceData method to replace the original target string value with the text in the TextBox.  Notice how the helper method, StringVisualizerObjectSource.Serialize is used here to serialize the text for passing back to the debuggee side.

I have left the comments in the event handler to show an alternate method of replacing the data.  You can also use the ObjectProvider.ReplaceObject method.  This method is simpler, in that it takes care of serializing the object for you.  I have provided both methods for instructional purposes.

Debugging Visualizers

The source code has complete comments on how to use the StringVisualizerObjectSource.DebugVisualizer method.  Also, watch the Debugging Debugger Visualizer video for a complete walk through of this process.

The DebugVisualizer function makes debugging a Visualizer a snap.  Follow these simple steps to debug your visualizer.

1.  The project used to start this Visualizer will need to reference Microsoft.VisualStudio.DebuggerVisualizers ( VS2005 use version 8 )  ( VS2008 use version 9 )

2.  The project used to start this Visualizer will need a reference to the Object Source project.  Ensure that you set Copy Local to True.

3.  Set desired breakpoints inside your Visualizer

4.  Call this method from another project

5.  Please see the following post if you have difficulties during debugging: System invalidcastexception unable to cast object of type x to type x

In your source test bench project, typically in the same location that you would normally place a breakpoint to launch the visualizer, place the following call:

SampleStringVisualizer.StringVisualizerObjectSource.DebugVisualizer(strTest);

When you now run the test bench project (or a real project) and when the above line of code executes, the visualizer will be started and when any breakpoints are reached in the Object Source code, Visual Studio will break and you can debug your visualizer just like any other program.

All this magic happens because the DebugVisualizer method calls the VisualizerDevelopmentHost method.  This is supplied by Microsoft and gets around the normal difficulties when debugging across two processes.  You can read the MSDN documentation on the VisualizerDevelopmentHost here.

Please Read This:  After you are done debugging your visualizer, you MUST remove the two above references and the call to the DebugVisualizer method.  If you don’t and then try to open the debugger visualizer using the normal methods, you will start having weird exceptions and get bummed out.  Trust me, I’ve been down that muddy road called, “what is going on highway?”

Summary

That is not very much code is it?  You can write your own visualizers.

There are plenty of example visualizers and articles on the Internet.  The MSDN documentation is very good also.

The wildest visualizer ever written is probably Mole.  You can download Mole, watch all the videos and read all the Code Project articles here: here at Mole’s Home Page.

I hope you can learn a good bit from this article, the two videos and the source code download.

Have a great day,

Just a grain of sand on the worlds beaches.


Mole v4.2 Update Released – New Features!!

January 19, 2008

Mole

Here is a bullet list of the changes.

  • Mole v4.2 now supports using Mole with WorkFlow (WF) applications. A new test bench project for WF was added to the Source and Test Benches solution.
  • “The Rock Star Hack of 2008!” – We at Team Mole have been trying for a long time to figure out a generic way for developers to launch Mole. Josh “Rock Star” Smith has finally breached this stone wall with his awesome hack. Mole has been modified so that Visual Studio can reconginze System.WeakReference as a supported Type that Mole can visualize. By using the WeakRefernce object as a wrapper, Mole can now be launched using any object type.

This release of Mole will change the way developers debug, period. Using the Rock Star Hack of 2008, you can launch Mole using any object type. You no longer have to have a specific Type attribute in the Mole.Visualizer.dll file to start Mole. Read the new article and watch the new video on launching Mole using the WeakReference object. You will be amazed!

Josh Smith wrote an outstanding blog entry,  The Rock Star Hack of 2008 that explains this feature in great detail.

While I was adding the new Workflow Test Bench program and getting Mole and WF all figured out, I ran into a bump in the carpet. I finally figured out what was causing the program.

Andrew Smith of Team Mole has blogged about this issue and you can read his blog entry SyncHashtable is not enumerable…

Mole’s Home Page – Download New Release Mole v4.2 and Updated PDF Manual

Updated Mole v4.2 Code Project Article – Mole For Visual Studio – With Editing – Visualize All Project Types

We suggest that you have a look at the videos that have been posted on YouTube. I added three more today.

1. View Video Mole v4.2 How Visualizers Are Started Up By Visual Studio

2. View Video Mole v4.2 With WorkFlow (WF) Applications

3. View Video Mole v4.2 New Generic Way To Start Mole, The Rock Star Hack!

View Mole Video Series On YouTube

Hope you enjoy and use Mole!

Just a grain of sand on the worlds beaches.


Mole v4.2 How Visualizers Are Started Up By Visual Studio

January 19, 2008

Mole

Team Mole recommends this video for all users of Mole.

Mole v4.2 will be released in the evening of 1/19/2007. 

This short video covers a very important topic, “how visualizers are started up by Visual Studio.”

I had a number of emails this week from developers with questions about why a certain object Type didn’t have a visuzlier data tip.

There is a big difference between what Mole and shows you, and what objects Visual Studio can use to start up a visualizer. This video covers this important topic.

This video will be a big help to all developers on using visualizers with their various project types.

View Mole Video Series On YouTube

Mole’s Home Page – Download Current Version of Mole and PDF Manual

Tip: If you watch the video from the YouTube site, there viewer the option to view the video in a larger format.

Enjoy Mole!

Just a grain of sand on the worlds beaches.


Listen to the Polymorphic Podcast about Mole

January 15, 2008

PodCast Icon
Josh Smith of Team Mole was recently interviewed by Craig Shoemaker of Polymorphic Podcast.

In the interview, Josh goes into the inside story behind Mole and how some features were developed. I liked the podcast because it brings back some very cool memories and very funny stories of Team Mole.  Josh also covers some technical topics to help the listener gain a better understanding of Visualizers and Mole.

You can listen to the podcast here: http://polymorphicpodcast.com/shows/mole/

Mole’s Home Page – Download New Release and Updated PDF Manual

Enjoy Mole!

Just a grain of sand on the worlds beaches.


Mole v4.1 New Features Video

January 13, 2008

Mole

This short video covers the new features introduced in Mole v4.1.

View Mole Video Series On YouTube

Mole’s Home Page – Download New Release and Updated PDF Manual

Enjoy Mole!

Just a grain of sand on the worlds beaches.


Mole v4.1 Update Released

January 13, 2008

Mole

Team Mole has been busy again.  We have taken some recent suggestions along with some items Josh and Andrew wanted and have released Mole v4.1.

Here is a bullet list of the changes.

  • Made changes to VisualSnapshot code to catch & handle possible exceptions caused by WinForm object property editing.
  • Added Full Type Name ToolTips to the TreeViews, MoleCrumbs and property grid Type column.
  • Added Show Namespaces option to have the TreeViews, MoleCrumbs and property grid Type column show the full type names.
  • Added ability to export the property grid to an .xml file. That file can then be imported to allow element comparisions.
  • Hide the Show Attached Properties CheckBox when not viewing WPF applications.

Mole’s Home Page – Download New Release and Updated PDF Manual

Updated Mole v4.1 Code Project Article – Mole For Visual Studio – With Editing – Visualize All Project Types

For the last week I have been sick in bed. I actually missed 4 days work and my weekend. I felt a little better today so I made the code changes and am releasing Mole v4.1.

Hope you enjoy and use Mole! 

Just a grain of sand on the worlds beaches.