I spent some time this week researching what would be needed to update some of my Visual Studio 2010 extensions to support Visual Studio 2012. I’ve now managed to do so, and would like to share what I found in case anyone else finds it useful.
Warning: This post was written and tested with the Visual Studio 2012 release candidate and I have no clue how well it will work on the final release. I’ll update it or post again once it comes out if needed.
The first thing to try was, of course, to take the existing code, migrate it into a VS2012 project, and update all references to Visual Studio assemblies. That worked, as far as building goes, but the extensions would still not work. It is not that they would cause any errors; they just didn’t do anything.
In this particular case, I focused on two of my extensions: KeywordClassifier and BetterXml. Both of them rely on the same mechanism, which was layering an
ITagger<ClassificationTag> on top of the tags produced by the original provider. This was done through the use of an
After a bit of debugging, I discovered the reason the original code was no longer working was because the
ITagAggregator<ClassificationTag> instance returned by Visual Studio would simply return an empty list when
GetTags() was called.
With some experimentation, I realized that while asking for an
ITagAggregator<ClassificationTag> no longer worked, asking for an
ITagAggregator<IClassificationTag> (that is, use the interface instead of the specific type) would indeed work. Plus, the same code would work just as well in VS2010!
return new KeywordTagger( ClassificationRegistry, Aggregator.CreateTagAggregator<IClassificationTag>(buffer) ) as ITagger<T>;
I was still not terribly thrilled about having to keep separate branches of the extensions with different project files and manifests to support both Visual Studio versions, so I started digging a bit more to see what other options there were. After a bunch of tests, I came up with something that works and allows me to keep a single VSIX file that works across both versions:
- Modify the extension manifest to make it installable under VS2012. I did this modifying the
<SupportedProducts>tag in the .vsixmanifest file to add an entry for VS2012, like this:
<VisualStudio Version="11.0"> <Edition>Ultimate</Edition> <Edition>Premium</Edition> <Edition>Pro</Edition> <Edition>IntegratedShell</Edition> <Edition>VST_All</Edition> </VisualStudio>
Now, I do not know if these are the correct edition strings, though, but they work with the VS2012 release candidate ultimate edition that is in MSDN. If anyone knows what the right strings should be, let me know and I’ll fix it.
- I changed the MaxVersion attribute of the SupportedFrameworkRuntimeEdition tag to specify .NET 4.5. I don’t know if that is needed (or useful), but probably wouldn’t hurt
<SupportedFrameworkRuntimeEdition MinVersion="4.0" MaxVersion="4.5" />
- Build the extension and package using VS2010, without changing the existing (and VS2010-specific) assembly references.
After trying this, the two extensions would load and run just fine in both VS2010 and VS2012, even if just one of them had been installed. I guess that VS2012 might be doing some assembly redirection when the extension is loaded, to ensure references are loaded correctly despite the fact that they have changed versions for 2012.
On the plus side, I discovered that my XAML Classifier Fix extension is no longer needed in Visual Studio 2012, now that the team introduced an explicit
XAML Text classification.