One of the key changes in Visual Studio 2010 is the start of a move to a fully managed code implementation. Several aspects of the product are implemented in managed code using the Managed Extensibility Framework (MEF) - see Visual Studio 2010 New Features, Extensibility Points and Partner Opportunities for the full detail, and watch this video by Paramesh Vaidyanathan and Rico Mariani for an overview of the direction Microsoft is taking here.
I want to see how easy it is to create a simple extension for Visual Studio 2010, in terms of development and deployment, and so I start by downloading the SDK. This SDK includes all the bits needed for developing extensions to Visual Studio, along with a number of project templates to get you started.
Notice the description of the selected template - this isn't just a blank project, it actually implements an editor adornment, which in this case highlights every character 'a' within the editor document by putting it within a box.
What I would like to do as a first project is to implement a similar editor adornment, but in this case look for block comments which contain the text "TODO:" as the first non-whitespace text in the comment, and highlight the entire comment in a graduated red box (similar to the blue selection box we have in VS 2010). This highlight will extend to the first line which isn't a comment (or which is a comment, but only has whitespace characters). So something like this:
So I create a new Editor Text Adornment project, and take a look at what comes out
We get two C# files and a .vsixmanifest file - which I guess we should take a look at first. Double clicking on this opens up a property editor
I'm not going to dig into this in detail for the moment, but looks like this gives us the ability to define what we want packaged up with our extension in terms of additional files and referenced packages and assemblies. We can also name our extension and define some icons which appear in the Extension Manager. Finally we can restrict supported versions of Visual Studio and the framework if we so desire.
OK, now lets look at the classes. AdornmentFactory.cs is responsible for two things - firstly it defines a new layer onto which our class will draw its adornments.
And secondly the class itself implements IWpfTextViewCreationListener which allows it to hook into IWpfTextView events in the TextViewCreated method.
I don't like the way this is implemented - ie having the contructor "do stuff" with a class which is never used, a very non-intuitive bit of code in my opinion, it would look better with a static method which itself calls the constructor, eg ScarletCharacter.RegisterView(textView).
The constructor of our adornment class itself simply caches the view, and the adornment layer which we registered for this view, along with some graphics objects (Brush, Pen etc not shown above) and registers a LayoutChanged handler for this view.
This event handler gets details of each change made in the editor, and is called when the editor is first opened also. The CreateVisuals implementation by default deals with highlighting all 'a' characters in the file, but we want a different implementation. So lets rename this adornment class to TodoHighlighter and we should get away with changing CreateVisuals to achieve our purpose.
This is similar to the original implementation, except here we go through all lines in the editor, looking for those which start a TODO block, and for each of these determine the extent of the block and then create the highlight based on a SnapshotSpan. TODO blocks are detected with these methods:
Finally we can add some sparkle to the default brush used to draw the highlight - we wanted a gradient red, similar to the blue used for normal highlight in the WPF based text editor. Lets modify the constructor code as follows:
We should be ready to rock. Lets F5 this bad boy and see what comes out. Well, as is so happens, F5 spins up a new visual studio instance running under the debugger and by default took ages. I stopped the debugger, changed Options to disable Historical Debug, and tried again - much better.
So in this debug Visual Studio, I create a console app, and modify Program.cs with a TODO comment, and tada:
Great stuff, maybe needs some tweeking but the concept is proven. Now what do we do about installing this into Visual Studio? Lets examine what has actually been generated for us.
This is the contents of bin debug for this project. We have what we would expect, but also this TodoCustomHighlighter.vsix file. This is actually the zipped package file which Visual Studio now recognises for extensions. If we go into the Extension Manager, we should be able to select this and install it.
Hmm, no options there for installing from a local drive. Lets just double click on the vsix file. This seems to work fine:
So I click install, then restart Visual Studio as suggested. Nothing, no sign of my extension in the Extension Manager, and no highlighting of my TODO comments.
Perhaps it didn't hear me. I try installing from the vsix again. This time it fails with the following error in the log:Install Error : Microsoft.VisualStudio.ExtensionManager.AlreadyInstalledException: TodoCustomHighlighter is already installed.
This is weird - looks like Visual Studio recognises that the extension has been installed, but for some reason is not running it, or even acknowledging its existence. Looking at the options dialog, there are some extension manager options.
This has the option Load extensions from my local application data folder, but this is unchecked and also disabled. I am running the Windows 7 RTM, so this may be a UAC issue. I shut down VS and restart in escalated mode by holding down Ctrl-Shift whilst clicking the Visual Studio taskbar icon. This allows me to check the Load extensions... option - great.
Except that even now, before or after restarting Visual Studio, I still don't get my "installed" extension. Something strange is going on here. Time to check the event log and the registry to see if we can find out what is happening.
OK I find the extension in HKCU\Software\Microsoft\VisualStudio\10.0Exp\ExtensionManager\EnabledExtensions containing:
Name: TodoCustomHighlighter..fbe86c05-ea59-4bb6-b982-b1478430e535,1.0Value: C:\Users\Chris\AppData\Local\Microsoft\VisualStudio\10.0Exp\Extensions\TodoCustomHighlighter\1.0\
Looking for that specified directory, all I have is C:\Users\Chris\AppData\Local\Microsoft\VisualStudio\10.0Exp\Extensions - which is empty. Possible that something went wrong because I didn't have Load extensions from my local application data folder enabled when I first installed the extension. I will delete this registry value, and see if that allows me to install again.
Nope, same problem. Although I notice the TodoCustomHighlighter\1.0 folder has appeared in the root of the C drive for some reason. Moved this to the path specified above, but still doesn't load.
It's annoying, but I am going to have to leave it there for now. I will monitor some of the VSX blogs for any solutions or workarounds to this problem and update this post when I have more info, but for now it looks like I have a working extension which just can't be installed.
EDIT: I found a workaround by re-reading Scott Hanselman's post on the Demo Dashboard extension - if you just drop the DLL into C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\Components and restart Visual Studio, the extension is installed, although still isn't listed in the Extension Manager. Perhaps this area isn't quite there in this beta 1 release for home grown extensions?
ADDITIONAL: Finally worked it out - I noticed that I could download and install .vsix from the Visual Studio Gallery but that these had an additional part to the filename beneath the Extensions area in AppData. I also noted that I left the Author field blank in the .vsixmanifest file - so I fill this in with "roundthecampfire", and replace the name GUID with a new one so that this looks like a new component.
Now if I rebuild all and reinstall from the .vsix file, it shows success (as it did previously), but if I start Visual Studio it's a different story:
Finally - I have what I wanted all along, a standalone installer file for my extension, and a good user experience for installing it, enabling/disabling it, and for uninstall. The process was tougher than it needed to be for me, but this is beta software, and I guess I should have taken more notice of the little red exclaimation mark next to Author in the .vsixmanifest editor. Hopefully come the RTM this will cause a compilation failure, or an install failure rather than feining success.
Theme design by Jelle Druyts
Powered by: newtelligence dasBlog 2.3.9074.18820
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2010, Chris Ballard
E-mail