Viasfora v1.6 Released

Today I published a new update to my Viasfora extension for Visual Studio 2010-2013. One of the new features in this build is a text editor margin that could be useful to other fellow developers working on extending the Visual Studio Text Editor.

[caption id="attachment_1412" align="alignnone" width="507"]Developer Margin Developer Margin[/caption]

One of the reasons why I implemented this was that I when I needed to extend Viasfora to support new file formats and other document types, I always had to resort to setting breakpoints in the debugger to figure out things such as the content type and how the editor worked, and this gets tiresome real quick!

In this first iteration, the margin exposes the following information:

  • What buffers compose the buffer graph: Complex editors in VS often require layering multiple buffers with different content types on top of each other, and this will let you easily see what those buffers are. For example, an ASP.NET MVC Razor editor might contain several buffers, such as the main Razor document, one containing the underlying CSharp code generated for the document, another containing the JavaScript code, plus a few other projection/elision buffers.Because the content type is the key to extending the text editor, it is very useful to be able to examine how the buffer graph is made up and making sure you don't have multiple instances of your extension on multiple buffers interacting poorly with one another.
  • Exploring individual buffers: Besides visualizing the buffer graph, you can also explore the contents of the each of the buffers in a separate editor window. One side benefit of this is that it makes it easy to check out what the generated code for many text editors is like :).
  • Exploring Content Types: In Visual Studio, content types can inherit from one another. For example, the "RazorCSharp" content type inherits from "Razor", which in turn inherits from "htmlx", and so on. With Viasfora, you can now easily inspect the content type tree.
  • Keeping track of the caret position: Visual Studio does a nice job of telling you where you're located in the document at any given time with the line/column slots in the status bar. However, if you're implementing text editor extensions such as classifiers, you often will be tracking things based on the actual position in the text buffer, rather than as line/column pairs. The margin adds such a counter on the bottom right.

Eventually, I hope to add other useful features to the margin, but suggestions are always welcome. Enjoy!

Pretty QuickInfo Tooltips and VS Themes

A Visual Studio Extension can extend quick info tooltips by implementing the IQuickInfoSource interface (and a few other things).

Most of the samples implement the AugmentQuickInfoSession() method by adding string values into the quickInfoContent collection. However, you can also add UIElement objects when you want to present tooltips that have complex content.

I implemented this for Viasfora as part of the XmlQuickInfoSource class, in order to present a much nicer tooltip for XML namespace prefixes. The end result was this:

[caption id="attachment_1400" align="alignnone" width="520"]Tooltip on Light Theme Tooltip on Light Theme[/caption]

It looked great. That is, until I tried it on Visual Studio 2012/2013 using the Dark Theme, which turned out to be unreadable:

[caption id="attachment_1401" align="alignnone" width="520"]Tooltip on Dark Theme Tooltip on Dark Theme[/caption]

After a lot of researching, I ran into the answer: There is an EnvironmentColors class included in the Microsoft.VisualStudio.Shell.(11|12).0.dll assembly, which will contains styles you can use to theme your WPF elements to properly match the selected theme.

For my needs, I could just use the ToolTipBrushKey, ToolTipTextBrushKey and PanelHyperlinkBrushKey properties to style my controls. However, I ran into a snag: The EnvironmentColors class is not available on the Visual Studio 2010 assemblies, which was a problem for me in order to support VS2010/2012/2013 with a single assembly.

While not a very pretty solution, I resorted to using Reflection coupled with the major Visual Studio version number in order to support this feature. The relevant pieces of code are:

private UIElement CreateInfoText(String xmlns, String url) {
var textBlock = new TextBlock();
Hyperlink hl = new Hyperlink(new Run(url));
textBlock.Inlines.AddRange(new Inline[] {
new Bold(new Run("Prefix: ")),
new Run(xmlns),
new LineBreak(),
new Bold(new Run("Namespace: ")),
// set styles in order to support other
// visual studio themes on 2012/2013
object tooltipBrushKey = VsfPackage.Instance.FindColorResource("ToolTipBrushKey");
if ( tooltipBrushKey != null ) {
textBlock.SetResourceReference(TextBlock.BackgroundProperty, tooltipBrushKey);
object tooltipTextBrushKey = VsfPackage.Instance.FindColorResource("ToolTipTextBrushKey");
if ( tooltipTextBrushKey != null ) {
textBlock.SetResourceReference(TextBlock.ForegroundProperty, tooltipTextBrushKey);
object hlBrushKey = VsfPackage.Instance.FindColorResource("PanelHyperlinkBrushKey");
if ( hlBrushKey != null ) {
hl.SetResourceReference(Hyperlink.ForegroundProperty, hlBrushKey);
return textBlock;

private Version vsVersion;

public object FindColorResource(String name) {
if ( vsVersion.Major <= 10 ) {
return null;
Assembly assembly = Assembly.Load(String.Format(
"Microsoft.VisualStudio.Shell.{0}.0, Version={0}.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
if ( assembly != null ) {
Type type = assembly.GetType("Microsoft.VisualStudio.PlatformUI.EnvironmentColors");
var prop = type.GetProperty(name);
return prop.GetValue(null, null);
return null;

Hope someone else finds this useful. Enjoy!

IClassifier and IDisposable

I've been troubleshooting some issues with Viasfora and noticed something that I definitely was not expecting:

It appears that if you implement an IClassifier extension, and also implement IDisposable, it will not be called by Visual Studio once the text buffer is released.

I have noticed this on Visual Studio 2013, but so far, I haven't fully verified if this is indeed the expected behavior, or if it is caused by something else I am doing. I do know of many other Visual Studio extensions that combine IClassifier with IDisposable, so if this turns out to be the default behavior, it could signal other extensions may be leaking resources.

Viasfora v1.2 Released

Viasfora version 1.2 has been released! Most of the work on this released went into significantly improving the performance of the extension, particularly around Rainbow Parentheses and the Keyword Classifier.

One of the issues that I ran into was that when both features were enabled, they could interact in ways that would easily kill performance, particularly causing the C# editor to blink the highlight on some words, which was not a good thing. Another big challenge was the JavaScript editor, which, because of how it parses JS (in VS2010, in particular), it becomes very sensitive on anything that forces tag updates.

Much of the extra performance work went into improving the lexing code to extract braces when the document changes. I'm still not terribly happy with the current code, but it seems to be holding up for now. Two of the things that improved this the most are keeping a list of all the braces found and then only doing partial invalidation when the document changes, and also providing a quick way to look up ranges of braces based on the document lines. Still lots of room for improvement here!

As for new features? Rainbow parentheses is now supported on VB (often asked about!). Initial support for F# is also provided, but I am sure the default set of F# keywords I chose for this version could use some improvement. If you're an F# fan, let me know of any suggestions!.

Viasfora v1.1 Published

Tonight I pushed a new version of my Viasfora extension for Visual Studio. In this version, I fixed some features that were not working on Visual Studio 2013 due to the introduction of a new HTML editor, particularly highlighting closing HTML tags.

What's exiting to me, however, is the new feature: Rainbow Parentheses:

[caption id="attachment_1388" align="alignnone" width="501"]Rainbow Parentheses Rainbow Parentheses[/caption]

This is a Visual Studio version inspired by one of my favorite Vim plugins. Features:

  • Supported for C#, C/C++ and JavaScript files.
  • Highlights {}, [] and () braces.
  • Supports 4 different nesting levels, format for each one can be customized through the Tools -> Options dialog (Rainbow Parentheses 1-4).

Comments, bug reports and feature requests are always welcome. Enjoy!

Introducing Viasfora

A couple of days ago, I unveiled Viasfora, my latest attempt at building a decently packaged extension for Visual Studio 2010, 2012, and 2013. I had already published a few VS Extensions before (Keyword Classifier, BetterXml, Line Adornments, and Xaml Classifier Fix), but it was not overly successful. The reasons for this were several:

  • I originally published those extensions not really as something useful in their own right, but rather as samples on how to implement VS extensions. They were successful in that regard, but none were ever very widely used.
  • While useful in their own right, the extensions weren't very polished. They were not very easy to customize and the code needed some cleanup to be easier to maintain.
  • The names, frankly, sucked.
  • I'm terrible at promoting stuff, so I never did much about them other than a few posts on this blog. I even was so absentminded that I uploaded BetterXml to the Visual Studio Gallery, only to forget to publish it. No wonder no one used it!

What is Viasfora?

Viasfora is a combination of my 3 most significant previous extensions. Keyword Classifier, BetterXml and Line Adornments. It puts them all in a single, nice package that includes full customizability through the Tools -> Options dialog in Visual Studio, including the ability to turn individual features on/off.

So what does Viasfora offer? Check the website for the full details, but here are some highlights:

  • Current Line Highlighting, a native feature in VS2013, but supported on VS2010 and VS2012.
  • Custom highlighting of Control Flow keywords, LINQ-related Keywords and Visibility keywords for C#, C/C++, JavaScript and Visual Basic (new!).
  • Highlighting of character escape sequences in C# strings, which makes it real easy to spot them!
  • Custom highlighting of XML namespace prefixes in XML/XAML/HTML documents.
  • Highlighting closing element tags in XML/XAML/HTML documents in a different color as the opening element tag. This is one of my favorite features and one I often miss from Vim.
  • Matching (through highlight) of opening/closing element tags in XML documents (new!).
  • Tooltips for easy lookup of XML namespace prefixes.

Hopefully having a nice (if simple) website for the extension with all the information makes it easier for people to find and get interested in it. As with my previous extensions, complete source is available on the < a href=''>github repository.

Where does the name come from?

Sorry, I still suck at naming :). The name Viasfora comes from my attempt of mixing the greek word "Diáfora" and, well, obviously VS for Visual Studio. It sounds catchy, I think!

Please let me know if anyone runs into any problems, bugs or feature requests.

SPListAnalysis: A sample DebugDiag v2.0 Analysis Rule

DebugDiag is a tool for collecting and
analyzing memory dumps. Version 2.0 was just
released and makes it extremely easy to write your own custom analysis rules using any language
that target the CLR.

SPListAnalysis is a sample analysis rule I implemented to show the basic steps involved in the process.
The rule does the following:

  • Iterates over all threads found in the process dumps to identify any threads that are
    querying an SPList object (or causing it to load the items contained therein).
  • Identifies the CAML
    query associated with the operation.
  • Generates a warning if the query contains more than 10 fields, loads all the fields in the list,
    or if the query fails to specify a RowFilter.
  • Prints the stack traces and query details for each matching thread.

The code for this sample can be found here.

This particular sample if very simple, consisting of a single class called SPListAnalysis,
which implements the IHangDumpRule interface to process one dump at a time. It also implements the
IAnalysisRuleMetadata interface to define the category and description for this analysis.

[caption id="attachment_1371" align="alignnone" width="755"]DebugDiag Analysis DebugDiag Analysis[/caption]

The basis for the analysis is looking at all threads that contain a significant function in the
call stack, and then looking for a matching object in the stack frames (similar to doing a !DumpStackObjects)

private void RunSPListAnalysis(NetDbgObj debugger)
// initialize report
foreach ( var thread in debugger.Threads )
// report findings

private void AnalyzeThread(NetDbgThread thread)
// ...
if ( ContainsFrame(thread, SPLIST_FILL_FRAME) )
dynamic obj = thread.FindFirstStackObject("Microsoft.SharePoint.SPListItemCollection");
if ( obj != null )
String viewXml = (string)obj.m_Query.m_strViewXml;
XDocument doc = XDocument.Parse(viewXml);
AnalyzeViewXml(thread, doc);

Reporting the results is mostly a matter of generating HTML. However, we can also generate
warnings that are included at the top of the report, allowing us to quickly alert the user
that something of interest was found in the dump:

private void ReportThreadsWithLargeSPQueries()
if ( threadsWithLargeSPQueries.Count > 0 )
StringBuilder sb = new StringBuilder();
sb.Append("The following threads appear to be executing SPList queries requesting many fields.");
    foreach ( int threadId in threadsWithLargeSPQueries.Keys )
  • {0} ({1} fields)
  • "
    threadId, threadsWithLargeSPQueries[threadId]);
this.manager.ReportWarning(sb.ToString(), "");

The resulting report will look like this:

[caption id="attachment_1372" align="alignnone" width="691"]DebugDiag Warnings DebugDiag Warnings[/caption]


Keyword Classifier v1.4

Published another minor update to my KeywordClassifier Visual Studio extension yesterday. The new version adds support for Visual Studio 2013 preview, and also adds a new feature: A custom classification tag to highlight escape sequences within strings:

Screenshot of string escape sequence

Use the "String Escape Sequence" classification tag to change the appearance of these. Enjoy!

Keyword Classifier 1.3 Released

I posted an update to my KeywordClassifier Visual Studio extension today. This update fixes the manifest so that Visual Studio 2012 compatibility is better detected, and also adds JavaScript support for both VS2010 and VS2012. Here's a screenshot of how it looks:

KeywordClassifier JS Screenshot

I also updated the version of the extension that is posted on the Visual Studio Gallery.

ClrMD: Fetching DAC Libraries From Symbol Servers

Last week, the first public beta of the Microsoft.Diagnostics.Runtime library was released. This is a very cool library that can be used to write automated dump analysis of processes hosting the CLR.

One of the first things you will need in order to use ClrMD is get a hold of the DAC library for the specific version of the CLR that your dump/live process is using. If this is a local dump/process, then you'll have the DAC handy, as it will be part of your .NET Framework installation (example: c:\windows\Microsoft.NET\Framework64\v2.0.50727\mscordacwks.dll).

If you're inspecting a dump from another machine, then you could also copy the mscordacwks.dll from the right folder in the remote machine. A more interesting option, however, is to dynamically fetch the right DAC library from the public Microsoft Symbol Server. ClrMD does not have built-in code to do this, and it can be a bit tricky, but it's possible to implement it relatively easy in many scenarios.

In order to do this, you first need find two native libraries and copy them over to the same directory your application executable is located:

  • dbghelp.dll
  • symsrv.dll

The right place to pick these up is as part of the Debugging Tools For Windows package. Remember that you need to pick these for the right bitness (x64 or x86) depending on your process architecture, which needs to match the architecture of the dump/process you're going to be inspecting. For this case, I picked the debugger tools package that comes with the Windows 8 SDK. When you install the tools from the SDK installer, these get installed to c:\Program Files (x86)\Windows Kits\8.0\Debuggers.

For this sample, you need to put the x64 and x86 versions of the libraries in the corresponding folder under .\dbglibs in the project folder. A custom build action will then copy the right version over to the output directory:

copy "$(ProjectDir)dbglibs\$(PlatformName)\*.dll" "$(TargetDir)"

The relevant code can be found in the DacLocator class. This class will load the dbghelp.dll library and initialize it. Using it is relatively simple:

dacloc = DacLocator.FromPublicSymbolServer(localCachePathTextBox.Text);
DataTarget dt = DataTarget.LoadCrashDump(dumpFileTextBox.Text);
String dac = dacloc.FindDac(dt.ClrVersions[0]);

Here we're just initializing the library to use the public Symbol Server and using the specified path as the local cache, and then attempting to locate the DAC library that is required. Finding the DAC itself is done using the SymFindFileInPath() function:

StringBuilder symbolFile = new StringBuilder(2048);
if ( SymFindFileInPath(ourProcess.Handle, searchPath, dacname,
timestamp, fileSize, 0, 0x02, symbolFile, IntPtr.Zero, IntPtr.Zero) ) {
return symbolFile.ToString();
} else {
throw new Win32Exception(String.Format("SymFindFileInPath() failed: {0}", Marshal.GetLastWin32Error()));

The rest of the sample is pretty straightforward: It just iterates through all objects in the heap, looking for HttpContext items and then
printing out some basic details of each one:

private IEnumerable FindHttpContexts(ClrRuntime clr) {
ClrHeap heap = clr.GetHeap();
foreach ( ulong addr in heap.EnumerateObjects() ) {
ClrType type = heap.GetObjectType(addr);
if ( type == null ) continue;
if ( type.Name != "System.Web.HttpContext" ) continue;

yield return GetHttpContextInfo(heap, addr, type);

private HttpCtxtInfo GetHttpContextInfo(ClrHeap heap, ulong addr, ClrType type) {
HttpCtxtInfo info = new HttpCtxtInfo {
Address = addr
ulong reqAddr = (ulong)type.GetFieldByName("_request").GetFieldValue(addr);
ClrType reqType = heap.GetObjectType(reqAddr);
info.Method = (string)reqType.GetFieldByName("_httpMethod").GetFieldValue(reqAddr);
info.Url = (string)reqType.GetFieldByName("_rawUrl").GetFieldValue(reqAddr);
return info;

Running the sample app will look something like this:

[caption id="attachment_1354" align="alignnone" width="670"] DacSample Screenshot[/caption]

The sample code can be downloaded here. Enjoy!