Running Custom Tracepoint Macros in Visual Studio


Debugging is the married partner of programming. Programming is hard. Debugging is hard. Doing both well is critical to having a good relationship. The most common features I use in debugging are straight forward breakpoints and the quick watch. (Writing small, Refactored functions seems to limit the amount of time needed for debugging for me, but everyone runs into tenacious bugs some times.) For tenacious bugs the more you know the easier it will be to find the bug, if easy is actually a suitable word. To that end I introduce the Tracepoint.

If you know all about Tracepoints then I am spicing it up—Bam!—with Visual Studio Macros. This article demonstrates the Tracepoint with macros.

A Tracepoint is basically a Breakpoint with options: Tracepoints are designed to print pre-defined special keywords, run a Visual Studio macro, and optionally continue or halt execution. If you uncheck the continue execution option then Tracepoints act like Breakpoints.

Reviewing Tracepoint Basics

When you set a Breakpoint in Visual Studio a small red circle icon is placed in the margin of the IDE. When you set a Tracepoint the icon will appear as a diamond. The easiest way to set a Tracepoint is to right-click on a line of code and click Breakpoint|Insert Tracepoint (see Figure 1). The Insert Tracepoint option is the same as picking the "When Hit" option from the Breakpoints window's context menu (see Figure 2). However, you insert a Tracepoint the "When Breakpoint is Hit" dialog is used to manage the Tracepoint.

Click here for larger image

Figure 1: The When Breakpoint Is Hit dialog is used to manage Tracepoints.

Click here for larger image

Figure 2: The Breakpoints window is the central location for managing all breakpoints.

The "When Breakpoint Is Hit" dialog contains the three options for managing Tracepoints. The "Print a message" option behaves like the System.Diagnostics.Debug.Print function in Windows applications, supporting sending text to the Output window. You can use the pre-defined special keywords, like $FUNCTION, to display formatted information like the function and the thread id ($TID). By default the Continue execution option is checked allowing the code to continue running. Uncheck Continue execution (Figure 1) to make the Tracepoint behave like a Breakpoint, stopping execution.

The middle option "Run a macro" let's you pick from a list of pre-defined macros. If you write a macro in the Macro IDE then your macros will appear in the dropdown too. It is this option that we are most interested in here.

Running a Custom Macro When a Tracepoint is Hit

Visual Studio is fully customizable through the EnvDTE, EnvDTE80, and EnvDTE90 assemblies. You can manipulate and control the IDE by writing wizards or just macros that call into the .NET Framework, especially by using the features of the EnvDTExx (DTE stands for Design Time Environment).

Tip: You can run a macro directly by select Tools|Macro Explorer and double-clicking on pre-defined macros.

Of course, Visual Studio already ships with dozens of pre-defined macros that you can pick from (in the Tracepoint dialog) or use as learning aids to help you implement custom macros. VB programmers have leg up with Macros because the Macro language is basically VB. To open the Macros IDE select Tools|Macros|Macros IDE. Another nice feature of the Macros IDE is that it is a lot like the Visual Studio so the features and uses should be readily recognizable (see Figure 3).

Running Custom Tracepoint Macros in Visual Studio

Click here for larger image

Figure 3: The Macros IDE is very similar to the Visual Studio IDE, and the Macro language is VB.

You can define macros as subroutines or functions, and macros can have parameters. Macros that are run by the Tracepoint dialog need to be subroutines without parameters because they are invoked by MSCORLIB.DLL and the core library is not designed to know about your input parameters or return functions. To recap if you want to design a Tracepoint macro it needs to be a public subroutine with no parameters written in VB.

As a presenter it is often the case that when focusing on a bit of code in a public forum, presented on a projector it is useful to increase the size of the fonts of the code under discussion. To that end I implemented GrowTheFonts and ShrinkTheFonts. GrowTheFonts increase the font-size in Visual Studio (not the Macros IDE), and ShrinkTheFonts decreases the font size when it's called. Listing 1 contains the implementation of GrowTheFonts and ShrinkTheFonts.

Listing 1: GrowTheFonts and ShrinkTheFonts changes the font size in the Visual Studio IDE when the macros are called.

  Imports System
  Imports EnvDTE
  Imports EnvDTE80
  Imports EnvDTE90
  Imports System.Diagnostics
  Imports System.Reflection
  Public Module Module1
      Sub GrowTheFonts()
          Dim textEditorFontsAndColors As Properties
          textEditorFontsAndColors = _
            DTE.Properties("FontsAndColors", "TextEditor")
          textEditorFontsAndColors.Item("FontSize").Value += 12
      End Sub
      Sub ShrinkTheFonts()
          Dim textEditorFontsAndColors As Properties
          textEditorFontsAndColors = _
            DTE.Properties("FontsAndColors", "TextEditor")
          textEditorFontsAndColors.Item("FontSize").Value -= 12
      End Sub
  End Module

Listing 1

In the Macros IDE an instance of EnvDTE already exists as the DTE object. In the code example the DTE object is used to request "FontsAndColors" from the "TextEditor", where TextEditor represents the code editor in Visual Studio. Once retrieved the "FontSize" is request through the Item property and the font is arbitrarily adjusted larger or smaller as the case may be.

Note: To get an idea how extensive the extensibility model is for Visual Studio check out the object model chart at http://msdn.microsoft.com/en- us/library/za2b25t3(VS.80).aspx.

After defining your macro you will see it listed in the Tracepoint dialog as one of the available macros (see Figure 4).

Click here for larger image

Figure 4: The custom macros available from the dropdown list in the Visual Studio IDE.

Don't be confused by the simplicity of the two macros in Listing 1. The Visual Studio Environment has a very large and rich object model. If you can imagine it you can probably figure out a way to do it. For an example of how rich IDE interaction can be I encourage you to download Developer Express' CodeRush tool. CodeRush interacts in very diverse and visual ways to help you generate code, making it probably one of the best examples of what is possible.


A Tracepoint is a Breakpoint that is designed to supported integrated code tracing, running custom (or canned) macros, and optionally permitting execution to continue or stop. What you want the Tracepoint to do when "hit" is up to you. If you can define the macro (or find the right existing one) then you can make tracing and debugging a much more detailed part of your development experience.


Paul Kimmel is the VB Today columnist for www.codeguru.com and has written several books on object-oriented programming and .NET. Check out his upcoming book LINQ Unleashed for C# now available on Amazon.com and fine bookstores everywhere. Look for his upcoming book Teach Yourself the ADO.NET Entity Framework in 24 Hours. You may contact him for technology questions at pkimmel@softconcepts .com. Paul Kimmel is a Technical Evangelist for Developer Express, Inc, and you can ask him about Developer Express at paulk@devexpress.com and read his DX blog at http:// community.devexpress.com/blogs/paulk.

This article was originally published on July 6th, 2009
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date