Introduction
Sil is an addin for Visual Studio that lets you quickly disassemble and inspect code. How does it work?
First, find some code that you're interested in:

Next, right click on the method name (or property, or class, etc.) and choose 'Disassemble':

Finally, the disassembly for your selection is shown in a new document window, with some extra functionality such as the ability to show or hide the source comments:

Why would we care about the disassembly?
1. Problem Solving
C# has a lot of syntactic sugar - lambda expressions, linq, using
statements, multicast delegates and so on. Sometimes, if you're investigating a bug or a problem, it can help to see what's actually going on at a lower level in your code.
2. Education
There are many things we learn about .NET and C# - and these are often quite high level. It's great that we don't have to care about what assembly is generated by the constructs we use. However, most of us developer types are nerds and tinkerers - we want to understand what's going on, how it works and broaden our knowledge. We all know that a using
block will dispose of its target IDisposable
object even if an exception is thrown - but how? If we catch an exception as type System.Exception
and silently consume it, our code will continue to execute - right? But what if it's a ThreadAbortException
? That automatically gets re-thrown - how? Seeing the assembly can teach you more about how C# and the .NET Framework actually work.
In this article, I'll show you how to use Sil, and also describe how it works - you can use the code as a starting point for your own Visual Studio addins. I will also be writing a short series of articles on Common Intermediate Language from the point of view of a .NET developer.
Let Me Try It!
If you're already sold on the prospect of madly inspecting each of your functions through the microscope and want to give Sil a try - just download the installer at the top of the article. Sil works as an addin for Visual Studio 2010 and 2012, there's also a standalone application that lets you disassemble any managed assembly.
Once you've installed Sil, just open any C# code and right click on something you're interested in. If it's a method name, the method will be disassembled. The same applies to properties, fields, events, delegates, enumerations and many other constructs. If Sil can't work out specifically what you're trying to disassemble, it'll disassemble the whole assembly for you.
The Standalone Application
You can run Sil as a standalone application. Open it up and choose 'File > Disassemble' or just drop an assembly onto the main window. One useful feature of the standalone app is that the entire assembly contents will be shown as a structured tree on the left hand side of the main window, which lets you look around in your assembly easily.

How Sil Works
Sil is not really very smart. It is broken into a few basic components.
Sil API
This class library provides the core functionality, an object for disassembling assemblies (which creates a DisassembledAssembly
instance). Alongside this, there are some other entities defined, such as DisassembledClass
and DisassembledEnumeration
.
Sil UI
This is a WPF User Control library that contains the main 'SilView
' user control. This view is used to present a DisassembledAssembly
. It also provides some basic functionality (such as turning on or off the comments).
Sil.SV2010
The Visual Studio 2010 addin. This adds the 'Disassemble' command to the code editor context menu and wires it up. It uses the Sil API for the logic of disassembling your selection, and the Sil UI to present it in a tool window.
Sil.SV2012
The Visual Studio 2012 addin. This adds the 'Disassemble' command to the code editor context menu and wires it up. It uses the Sil API for the logic of disassembling your selection, and the Sil UI to present it in a tool window.
Sil
The standalone application. This is a WPF app that uses the API to disassemble an assembly, and presents it via the Sil UI.
Sil also uses some other external components.
ildasm
The ildasm tool from Microsoft is used to actually disassemble the assembly.
AvalonEdit
The fantastic AvalonEdit library is used to create a syntax highlighted assembly text editor window.
Using the API
You can use the Visual Studio Addin, or the standalone application, but you can also use the API directly if you like, I'll highlight how the library is used with a few simple examples.
Example 1: Disassemble an Assembly
In this example, we use the Disassembler
object from the SilAPI to create a DisassembledAssembly
. We then write the raw IL to a file.
DisassembledAssembly disassembledAssembly =
Disassembler.DisassembleAssembly(@"SomeAssembly.dll");
using(var stream = new FileStream(@"SomeAssembly.il", FileMode.Create, FileAccess.Write))
using (var writer = new StreamWriter(stream))
{
writer.Write(disassembledAssembly.RawIL);
}
Some points:
- The
Disassembler
is an object you'll use a lot if you're working with Sil - it's the class that will actually perform the disassembling operation. - A
DisassembledAssembly
not only contains the raw IL, but also the classes, structures, events and so on.
Example 2: Discover Classes in an Assembly
A DisassembledAssembly
object contains a graph of the contents of the assembly. This means you can enumerate through various elements of an assembly.
DisassembledAssembly disassembledAssembly =
Disassembler.DisassembleAssembly(@"SomeAssembly.dll");
foreach (var disassembledClass in disassembledAssembly.Classes)
{
Console.WriteLine("Found class: " + disassembledClass.ShortName);
Console.WriteLine("Fields: " + disassembledClass.Fields.Count());
Console.WriteLine("Methods: " + disassembledClass.Methods.Count());
}
Some useful properties like this on the assembly are:
Classes
: The classes defined in the assembly AllClasses
: The classes defined in the assembly, including nested classes Structures
/ AllStructures
: Gets structures in the assembly, optionally including nested structures Interfaces
/ AllInterfaces
: Gets the interfaces Delegates
/ AllDelegates
: Gets the delegates Enumerations
/ AllEnumerations
: Gets the enumerations AllFields
: Gets all fields in all objects AllProperties
: Gets all properties in all objects AllEvents
: Gets all events in all objects AllMethods
: Gets all methods
Example 3: Searching for an Entity in an Assembly
In client applications like the Visual Studio Addin, we often know the long name of what we're looking for, and what it is (e.g., when the user right-clicks on a class, we know it's a class they've selected and what its full name is). The API exposes a method for searching an assembly.
public static void SearchAssembly()
{
DisassembledAssembly disassembledAssembly =
Disassembler.DisassembleAssembly(@"SomeAssembly.dll");
DisassemblyTarget target = new DisassemblyTarget
(DisassemblyTargetType.Interface, @"SimeAssembly.ISomeInterface");
DisassembledEntity entity = disassembledAssembly.FindDisassembledEntity(target);
if(entity != null)
Console.WriteLine(entity.RawIL);
}
Where Next?
From here, my plan is to write a short series of articles on Common Intermediate Language, as a reference for those who might want to learn a bit more about it. I've got some plans for Sil as well. Currently on the roadmap, I'm looking at:
- An automatic 'annotate' feature - if you select a line of assembly, there's a human readable description of what it means at the bottom of the screen.
- The ability to disassemble a selection of code, for example, a few lines of a method.
- Support for the Assembly Tree in the Addin, not just the standalone application.
If you have a particular desire for a feature or would like to get involved, get in touch! You can find the code on GitHub at github.com/dwmkerr/sil.
Known Issues
There are a few issues to be aware of when working with Sil.
- Visual Basic is not supported. It might work - I haven't tried. Support for VB is not on the roadmap, but if I get enough requests for it, then I'll certainly add it.
- I've seen some oddities with disassembling template classes - sometimes, the correct class cannot be found. This will be resolved very soon, you can follow the progress on GitHub.
- The project you're working on has to be built and up to date for Sil to be able to disassemble it. If you make changes to your code, then build it before you run Sil.
History
- 7th June, 2013: Initial version