Microsoft & .NET Running Custom Tracepoint Macros in Visual Studio

Running Custom Tracepoint Macros in Visual Studio

Introduction


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).





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.


Summary


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.


Biography


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 [email protected]
.com
. Paul Kimmel is a Technical Evangelist for
Developer Express, Inc, and you can ask him about Developer
Express at [email protected]
and read his DX blog at http://
community.devexpress.com/blogs/paulk
.

Latest Posts

Related Stories