Paul’s jabber


Maintaining a VSPackage that’s targeting Visual Studio 2005 and Visual Studio 2008
August 29, 2008, 2:45 pm
Filed under: Software, Uncategorized

I recently had the task of migrating a Visual Studio 2005 VSPackage, (a custom project type to be more precise) to Visual Studio 2008. Obviously having the VSPackage functional in VS 2008 alone was not good enough, we needed it to work in VS 2005 too.

After googling around I found a very interesting and helpful post about making a VSPackage run in both VS 2005 and VS 2008:

http://weblogs.asp.net/soever/archive/2008/06/04/use-vs2008-to-create-a-vspackage-that-runs-in-vs2008-and-vs2005.aspx

In the above scenario the package would basically be built against the VS 2005 SDK’s MPF (Managed Package Framework), but would then be registered under different Visual Studio registry hives i.e. 8.0/8.0Exp (VS 2005) and 9.0/9.0Exp (VS 2008). I then encountered a problem with the retrieval of the MSBuild path from the registry. This occurs within the ProjectBase source code in the Microsoft.VisualStudio.Package.Utilities.GetMsBuildPath(…) method. The Utilities class of the VS 2008 SDK , which contains this method, can be found in the following location;

%VSSDK90Install%\VisualStudioIntegration\Common\Source\CSharp\Project\Utilities.cs

You’ll find the VS 2005 SDK version of the Utilities class in the same location, but obviously under your VS 2005 SDK install path instead. You might have noticed that the VS 2005 SDK version of the GetMsBuild(…) method searches for the MSBuild path in only a single place in its VS hive:

Software\Microsoft\VisualStudio\8.0\MSBuild\MSBuildBinPath.

This registry value however does not exist in the VS 2008 registry hive (9.0) and therefore an exception is thrown when we try and run the VSPackage in VS 2008. If on the other hand you look at the VS 2008 SDK version of the GetMsBuildPath(…) method, you’ll notice that it attempts to find the MSBuildBinPath registry value in the same location as above and if it can’t it then tries to find it under the MSBuild registry hive:

Software\Microsoft\MSBuild\ToolsVersions\3.5\MSBuildToolsPath.

Now, you may say that the obvious solution would be to simply integrate the VS 2008 SDK’s code in the VS 2005 SDK’s code thereby making the VS 2005 SDK look for the MSBuild path in two locations in the registry. Have I tried it? Yes. Does it work? Yes. Is it a clean and elegant solution? I don’t think so. Not to mention that we would then have to maintain this customized code, meaning that every developer that may work on this project in the future would have to customize his/her copy of the VS 2005 SDK.

In order to implement a more elegant and maintainable (in my opinion) solution, I’ve opted to create separate assemblies for VS 2005 and VS 2008. Since all of the modifications needed to migrate a VSPackage from VS 2005 to VS 2008 are contained within the solution (.sln) and project templates (.csproj) of my projects, we can simply have separate solutions and projects opening the same code, but targeting different VS SDK MPF’s and registry hives. I converted the VS 2005 VSPackage to a VS 2008 VSpackage using the following tutorial.

http://msdn.microsoft.com/en-us/library/cc512930.aspx

Each developer working on the VSPackage can now simply check out the source code and open either the VS 2005 or VS 2008 solution depending on which IDE he/she is using.

Additionally for our WIX deployment we now simply have different .wxs deploy fragment files to register the VSPackage under the correct VS hive depending on what IDE the end user has installed. Have a look at the following article for deploying a VSPackage, which among others includes an implementation using WIX:

http://msdn.microsoft.com/en-us/library/bb458038.aspx

If anyone has any other ways of doing it, please let me know.


No Comments Yet so far
Leave a comment



Leave a comment
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>