Introduction
In the distant past, developing a plug in meant obscure
semi-documented COM interfaces and win32 development with C++. In recent years,
.NET and MSVS have made it easier. There are a few examples of how to do this,
but not many that make it easy. The goal of this project was to create a
framework for building simple MSVS plug-ins, and provide a few examples that
use some of the C# interfaces with COM to manipulate code and project files.
Architecture
The
AddInWorker class wraps adding a set of related commands to the Tools menu. Another
class CommandStruct wraps menu item name, icon, and calling a delegate. The
idea was multiple menu items would need to access an instance’s shared data,
such as presenting a preferences form, or multiple ways to run similar related
operations.
Using the Code
For testing there needs to be a shortcut added to Visual
Studio’s Addins folder that points to the .dll. MSVS generates the file
automatically when creating a new add in solution. When using the example code
provided, the shortcut file needs to be edited and moved into place.
For MSVS installed on the author’s system:
C:\Documents and Settings\prb\My Documents\Visual Studio 2010\Addins\
Has a file: MSVSAddIn - For Testing.AddIn
The line:
<Assembly>C:\Documents and
Settings\prb\Desktop\MSVSAddIn\MSVSAddIn\bin\MSVSAddIn.dll</Assembly>
Points to the .dll being tested, or the final .dll when
ready to deploy.
<extensibility xmlns="http://schemas.microsoft.com/AutomationExtensibility">
<hostapplication>
<name>Microsoft Visual Studio Macros</name>
<version>10.0</version>
</hostapplication>
<hostapplication>
<name>Microsoft Visual Studio</name>
<version>10.0</version>
</hostapplication>
<addin>
<friendlyname>MSVSAddIn - PRB</friendlyname>
<description>MSVSAddIn - By Phil Braica</description>
<assembly>C:\Documents and Settings\prb\Desktop\Research Articles\MSVSAddIn\MSVSAddIn\bin\MSVSAddIn.dll</assembly>
<fullclassname>MSVSAddIn.Connect</fullclassname>
<loadbehavior>1</loadbehavior>
<commandpreload>1</commandpreload>
<commandlinesafe>0</commandlinesafe>
</addin>
</extensibility>
Examples
Misc
There is a MiscCommands class that provides access to a
configuration form and an about form, these are the simplest examples of how to
use the framework provided to make new commands.
Doxygen
This example plug-in runs an external tool over the current
solution and generates the Doxygen documentation, and loads it into a viewer.
Doxygen is a good robust tool for parsing all of the comments and generating
HTML documentation that describes the detailed design. This part of the example
shows how to launch another process, monitor it, deal with some common possible
problems and do so somewhat gracefully. When running a thread, it is possible
the new process doesn’t finish so another thread is used to monitor it. Doxygen
uses a graphing tool called “dot.exe” which takes text descriptions of graphs
and diagrams and generates images on the fly. In the authors opinion it is one
of the nicest most interesting features of Doxygen. On very, very large things
(such as huge state machine diagrams generated from code)it sometimes takes so
much time it can lock up trying to optimally layout the diagram. A separate
thread is used to monitor dot.exe and kills it if it appeared to jam. The
viewer is a quick example of how to view HTML with C# in the simplest way.
Add Property
Takes a highlighted member variable snippet of C# code and
turns it into (best effort) a property with a protected member variable.
It will accept and deal with initial values, accessors,
modifiers, etc.
int a = 2;
protected object b = new object();
public static List<double> c;
and generate:
protected int m_a = 2;
public int a
{
get
{
return m_a;
}
set
{
if (m_a == value) return;
m_a = value;
}
}
The class adds a second command to modify the behavior by
bringing up a modal form. I use it to add an initial set of properties to a new
control or class quickly.
Copywriter
The class provides two commands, to either copy write the
current file, or copy write all files in a solution. In both cases it tries to
check if the file was likely auto-generated, and if a copy write statement
already exists. In order to do that, the class must find the first code element
in the file, and grab the text that exists from the start of the file to the
first code element. Simple COM things like edit points, document interfaces and
the solution interfaces are used to find the beginning of the file, figure out
if the header is already present or should be added, and then add the header as
needed. This way the tools support for the language is leveraged to locate any
comments. Support for a few languages was added (VB, C#, C++, perl, etc.) and a
form to set the preferences was added.
Commenter
This class provides stub comments (or just bookmarks
depending on user preferences) of where every code element should be commented.
It is meant to help identify deviations from a code standard. The author tries
to always fill out the summary tags as a minimum level of documentation for
everything, and the tool provides a good check. The class is meant to provide a
decent example of sorting through code elements, their hierarchy and types in a
very basic way. There are other examples on that do a more advanced job, this
example is relatively basic and easy to extend by the reader.
References
http://www.codeproject.com/Articles/89913/Microsft-Visual-Studio-2005-Doxygen-Add-In
http://www.codeproject.com/Articles/173496/How-to-Create-a-Visual-Studio-Add-in-that-Launches
http://www.codeproject.com/Articles/324611/Extending-Visual-Studio-Part-2-Creating-Addins
Phil is a Principal Software developer focusing on weird yet practical algorithms that run the gamut of embedded and desktop (PID loops, Kalman filters, FFTs, client-server SOAP bindings, ASIC design, communication protocols, game engines, robotics).
In his personal life he is a part time mad scientist, full time dad, and studies small circle jujitsu, plays guitar and piano.