Introduction
This article will show you how Lutz Roeder's .NET Reflector can be made into an Add-In for Visual Studio.NET. It will be done using the ManagedAddIns framework.
Background
I started writing the ManagedAddIns framework when NUnitAddIn (a unit testing add-in project I have been working on) started becoming unmanagable. I have been developing it using VS.NET 2002 but it has worked on both 2002 and 2003 for a while. I wanted to start developing it using VS.NET 2003 whilst maintaining compatability with 2002.
For the Impatient
If you're impatient and just want to see the Reflector add-in running - here's how you do it. Install the latest version of ManagedAddIns.msi. That's all you will have to do! The new version includes the Reflector Add-In (make sure you uninstall any old versions first). Go to the 'Tools/Managed Add-Ins..' menu and select Reflector Add-In. The first time the Reflector Add-In loads it will prompt you to download Reflector. After the download Reflector should appear in a tool window.
Using the code
The add-in has been developed in 3 stages ranging in complexity from drag-and-drop to writing code that uses the Reflector SDK. At each stage there was a fully functional add-in with differing levels in intergration.
At its most basic level ManagedAddIns allows you to run pretty much any Windows Forms application as a VS.NET add-in. Simply select 'Managed Add-Ins...' from the VS.NET 'Tools' menu. The add-ins toolbox should appear (dock it if it appears in the middle of the screen). You can use this to add, connect and configure your add-in applications. To run Reflector as an add-in simply drag Reflector.exe onto the toolbox (click save if you want to keep it). To start the application double click or right click 'Connect' the Reflector entry. At this point Reflector should appear inside VS.NET in a tool window. You are ready to dock the tool window and start reflecting away.
There are a lot of applications where this is all you will ever need to do. Just drag-and-drop and start running as an add-in. On the other hand there are many applications that use tool windows in much the same way as Visual Studio. Whereas these can work fine as Managed Add-Ins (particularly if you uncheck 'Dockable' on their tool window) they don't feel as integrated as they could be. There is a tweak you can do in many cases to make tool windows appear as VS.NET tool windows. This is done by declaring the tool window in the application's .config file. Reflector is one of these applications and its tool window can be declared as follows.
="1.0"
<configuration>
<configSections>
<section name="managedAddIns"
type="MutantDesign.ManagedAddIns.ManagedAddInsConfiguration,
MutantDesign.ManagedAddIns" />
</configSections>
<managedAddIns>
<managedAddIn name="Reflector">
<toolWindows>
<toolWindow type="Reflector.UserInterface.ToolWindow" />
</toolWindows>
</managedAddIn>
</managedAddIns>
</configuration>
As you can see a 'managedAddIns' config section is defined. You will need to copy 'MutantDesign.ManagedAddIns.dll' from 'Program Files\ManagedAddIns\' to your application's directory. In this case all controls of type 'Reflector.UserInterface.ToolWindow' will be created as Visual Studio tool windows. The control's 'Text' property will be kept in sync with the tool window's caption and when the control is made visable the tool window will be activated.
This kind of tool window works well when the control is a container and you want the control's 'Text' property to be used as the tool window's caption. In some cases you way want the control itself (rather than its contents) to be be parented by a tool window. In this case you can declare the tool window as follows. This would place the control called 'testSuiteTreeView' in a tool window with the caption 'Test Suite'.
<toolWindow name="testSuiteTreeView" child="true" caption="Test Suite" />
At this point we have Reflector running inside VS.NET yet totaly oblivious to the fact. Wouldn't it be nice if we could right click on a method and have the IL come up in Reflector? Or even better right click on a VB method and have it decompiled as C#? ;) To do this we will need to hook into the guts of Reflector using the Reflector SDK. We will be writing a Reflector add-in to connect to our VS.NET add-in! To create a Reflector add-in you must implement the Reflector.ComponentModel.IPackage interface.
public interface IPackage
{
void Load(IServiceProvider serviceProvider);
void Unload();
}
The first minor issue was that Reflector is an EXE and it wasn't obvious how to compile against an EXE using VS.NET. What you can do is rename Reflector.exe to Reflector.dll and add that to you project references. Once you've done this exit Visual Studio and edit the .csproj file. Rename the reference to Reflector.dll (and the file) back to Reflector.exe. Once you've done this you're ready to start writing a Reflector add-in.
To use the Reflector .config and add-in source I wrote earlier, extract it into the same directory as Reflector. The pre-compiled 'Reflector.VSAddIn.dll' will only work with version 3.2.5.0 or Reflector. If you're using a different version you must recompile (it has been changing a lot recently so please check!). Add Reflector to the Managed Add-Ins toolbox and double click/connect it. Once Reflector has loaded inside VS.NET, select Reflector's 'Tools/Add-Ins...' menu item. Select 'Add...' and add the 'Reflector.VSAddIn.dll' add-in.
At this point Reflector's context menu items should appear on the VS.NET code context menu. You can now dissasembly, decompile and outline your code. Best of all you can use this as a jumping off point to do the same to code you're calling!
Points of Interest
If you would like the Reflector add-in (or any other add-in) to always load you will need to edit the 'Program Files\ManagedAddIns.exe.config' file. Change the 'startup' attribute to be true on the 'managedAddIn' element in question. It should end up looking something like this.
<managedAddInRef assemblyFile =
"C:\Program Files\Reflector\.NET Framework 1.1\Reflector.exe"
startup="true" />
You can also add URL based applications to the Managed Add-Ins toolbox. For example you can run Chris Sells' Wahoo! game as an add-in by adding the following URL.
http://www.sellsbrothers.com/wahoo/wahoo.exe