none
Do you need multiple solutions to create side-by-side VSPackages for multiple versions of Visual Studio? RRS feed

  • Question

  • I'm creating a Visual Studio extension (via VSPackage) and would like it to be available for both VS 2012 and 2013.  I first created the 2012 extension in VS 2012, and then upgraded my project so it could be opened in VS 2013, and added my 2013 project; so now I have both projects, VSPackage2012 and VSPackage2013, in a Visual Studio 2013 solution.

    When I set VSPackage2012 as the startup project, my extension does not get loaded into the VS 2012 Experimental instance at all.  When I set VSPackage2013 as the startup project, I see that my package constructor gets called twice, and the Debug Output shows that it is loading symbols for both VSPackage2012.dll and VSPackage2013.dll.  This later results in a CompositionContractMismatchException being thrown when trying to load the extensions settings; I'm pretty sure it is trying to cast a class type from the VSPackage2012 to the equivalent class type in VSPackage2013.  I can also see that both my extensions get added to "C:\Users\[Username]\APPDATA\LOCAL\MICROSOFT\VISUALSTUDIO\12.0Exp\Extensions\DansKingdom", but none get added to "11.0Exp", so it's clear that it is loaded both extensions in 2013, but neither in 2012.  The packages' VSIX manifest files specify that they are only available to be installed on their appropriate VS version.

    Ideally I would like to just use a single VSPackage to publish my extension to both VS 2012 and 2013, but I'm making use of the Team Foundation assemblies and I believe they require linking to the specific version of the assemblies i.e. 2012 (v11.0) or 2013 (v12.0); specifically the Microsoft.TeamFoundation.VersionControl.Controls assembly.

    So is there a way that I can have multiple VSPackages targeted at different versions of Visual Studio in the same solution.  I have extracted all of the shared code out into another project (about 95% of the code), so I would like to have all 3 projects in the same solution if possible, as it means faster development time and only having to build one solution to build all of the VSPackages, rather than constantly switching between solutions.  Or is this simply not supported?

    I have read through this page and this one as well as several pages they link to, but they don't really answer my question of how to setup my side-by-side VSPackages in VS.  Any advice you can give is appreciated.  Thanks.


    - Dan - "Can't never could do anything"




    • Edited by deadlydog Friday, March 7, 2014 12:04 AM
    Tuesday, February 25, 2014 10:08 PM

Answers

  • Due to my assembly version constraints mentioned in my other replies, I am not able to use a single project for both the VS 2012 and VS 2013 versions of my extension; I have a separate project in my VS 2013 solution for each.

    However, thanks to the link to DanielKzu's blog, I am able to get my VS 2012 project to load in VS 2013 without needing to be converted to a VS 2013 project.  This is important because the VS 2013 projects are not backward compatible with VS 2012, and if you want to debug/test your extension in the VS 2012 experimental instance, then you have to run/debug it from VS 2012.

    So now I am able to debug my VS 2013 extension in VS 2013, and my VS 2012 extension in VS 2012, without having VS 2013 constantly ask me to upgrade my 2012 project to 2013.  However, due to my assembly version constraint, I do still have to unload my VS 2012 project when debugging in VS 2013, otherwise it loads both extensions into my VS 2013 Experimental instance and I run into assembly version runtime errors; when opening my solution in VS 2012 is simply does not know how to load the VS 2013 project, so it does not have this problem.

    When I want to actually build my vsix files for release, I only need to build in VS 2013, as it will build both the VS 2012 and VS 2013 projects to their respective /bin/Release folders.

    Here is what my 2012 project's .csproj file looks like so that I can open the VS 2012 project in VS 2013 without it always prompting me to upgrade:

      <PropertyGroup>
        <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
        <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
        <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
      </PropertyGroup>
      <!-- This is the property that causes VS 2013+ to insist on one-way update of the project -->
      <PropertyGroup Condition="'$(VisualStudioVersion)' &gt;= '11.0'">
        <MinimumVisualStudioVersion>$(VisualStudioVersion)</MinimumVisualStudioVersion>
      </PropertyGroup>

    Thanks again to DanielKzu for his blog post!

    So now I have a single VS 2013 solution hosting my VS 2012 and VS 2013 VSPackage projects.

    If you want to look at my source code, again here is the link.


    - Dan - "Can't never could do anything"

    • Marked as answer by deadlydog Wednesday, March 12, 2014 6:02 PM
    Wednesday, March 12, 2014 6:02 PM

All replies

  • Hi,

    See if this helps:

    http://blogs.clariusconsulting.net/kzu/how-to-create-a-visual-studio-extensibility-project-that-is-compatible-with-vs-2010-2012-and-2013/


    MZ-Tools: Productivity add-ins for Visual Studio: http://www.mztools.com. My blog about developing add-ins: http://msmvps.com/blogs/carlosq/

    • Marked as answer by Anna Cc Thursday, March 6, 2014 7:54 AM
    • Unmarked as answer by deadlydog Thursday, March 6, 2014 9:05 PM
    Wednesday, February 26, 2014 6:33 AM
    Moderator
  • Thanks for the link Carlos.  I applied all of the msbuild targets to my VS 2012 project's .csproj file, but unfortunately I still have the same problem; it installs both the 2012 and 2013 extension assemblies in "C:\Users\[Username]\APPDATA\LOCAL\MICROSOFT\VISUALSTUDIO\12.0Exp\Extensions\DansKingdom", and neither of them in "C:\Users\[Username]\APPDATA\LOCAL\MICROSOFT\VISUALSTUDIO\11.0Exp\Extensions\DansKingdom".  I removed the msbuild targets from the .csproj file since they didn't change any of the behavior (but I might still put them back in).

    You can download my code and take a look at it here to see exactly what I am doing and why I might be having this problem; I find it hard to believe that nobody else has run into this situation, but can't find any other posts about this problem.

    Any other suggestions are appreciated.  Thanks.


    - Dan - "Can't never could do anything"

    Thursday, March 6, 2014 9:10 PM
  • Your solution contains two projects for the extension. The whole point of my post is to show how you DON'T need separate projects per VS version. 

    You also have quite a few properties in your .csproj which are provided by my targets file already (as explained in my blog), which should also be gone.

    Friday, March 7, 2014 4:20 AM
  • Thanks for the reply DanielKzu.  Some of the Team Foundation (TF) assemblies that I reference are located in completely different locations from VS 2012 to VS 2013, and in order them to work properly ALL of them have to use the same version.  Because of this I cannot simply include the references and set Specific Version to False; Specific Version has to be True.  Because of this a project can only work with VS 2012 OR VS 2013, which is why I have two projects.  One to reference the v11.0 TF assemblies, and another to reference the v12.0 assemblies, both with Specific Version set to True.

    After analyzing your Referencing SDK Assemblies code though, I think might be able to use a similar technique to include the proper assemblies all in one project.  My question is though, are these variables/references evaluated at compile-time or at run-time?  As I believe it will only work for me if they are evaluated at run-time, as I can include both versions of all assemblies in my package, but have it reference the appropriate set depending on the version of VS that is running.

    As for the properties provided by your targets file already in my .csproj file, these were added by VS 2013 automatically.  I did modify the <VisualStudioVersion> in the 2012 .csproj file though from 12.0 to 11.0 so that it would open in the VS 2012 Experimental Instance instead of the 2013 one.

    So do you know to answer to my question of if the msbuild target values get evaluated at compile-time or run-time?  I'm assuming it is at compile-time, but am not certain.


    - Dan - "Can't never could do anything"


    • Edited by deadlydog Wednesday, March 12, 2014 6:03 PM
    Friday, March 7, 2014 3:38 PM
  • So I tried creating a single project (as suggested by DanielKzu) and copied the msbuild properties into the .csproj file, and commented out the existing attributes which his code redefined).  I then copyied the version specific assemblies directly into my project (under a folder named as the appropriate VS version number) and referenced them from there.  I then edited to the .csproj file and changed the Hint Path to use the $(VisualStudioVersion), rather than a hard coded "11.0" or "12.0".  So this is what one of the references in my .csproj file looked like:

    <Reference Include="Microsoft.TeamFoundation.VersionControl.Controls, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>VersionSpecificReferences\$(VisualStudioVersion)\Microsoft.TeamFoundation.VersionControl.Controls.dll</HintPath>
    </Reference>

    If I left the Specific Version attribute as false, then VS would try and use some 11.0 assemblies and some 12.0 assemblies (even though they are in different subdirectories) and would give compile-time errors.  So I set Specific Version to true for all of them.  This way they all referenced the v11.0 assemblies and everything worked in VS 2012.

    When I switched and opened it up in VS 2013 though, by modifying the .sln file and the .csproj file's VisualStudioVersion attribute to 12.0, it was still referencing the v11.0 assemblies and launching the VS 2012 Experimental instance, only now because I was debugging from VS 2013 it was installing the extension to 12.0Exp, and not 11.0Exp, so the extension did not even show up in the 2012 experimental instance.

    Argh, why does this have to be so hard.  I believe Clarius's solution would work for me if I didn't have to deal with the Team Foundation assemblies.  For reference, the four that I'm using are:

    • Microsoft.TeamFoundation.Client
    • Microsoft.TeamFoundation.Controls
    • Microsoft.TeamFoundation.VersionControl.Client
    • Microsoft.TeamFoundation.VersionControl.Controls

    And I believe the one giving me problems is Microsoft.TeamFoundation.VersionControl.Controls because in 2012 it was a VS private assembly, and in 2013 it is a public one.


    - Dan - "Can't never could do anything"


    • Edited by deadlydog Wednesday, March 12, 2014 6:03 PM
    Friday, March 7, 2014 5:30 PM
  • Due to my assembly version constraints mentioned in my other replies, I am not able to use a single project for both the VS 2012 and VS 2013 versions of my extension; I have a separate project in my VS 2013 solution for each.

    However, thanks to the link to DanielKzu's blog, I am able to get my VS 2012 project to load in VS 2013 without needing to be converted to a VS 2013 project.  This is important because the VS 2013 projects are not backward compatible with VS 2012, and if you want to debug/test your extension in the VS 2012 experimental instance, then you have to run/debug it from VS 2012.

    So now I am able to debug my VS 2013 extension in VS 2013, and my VS 2012 extension in VS 2012, without having VS 2013 constantly ask me to upgrade my 2012 project to 2013.  However, due to my assembly version constraint, I do still have to unload my VS 2012 project when debugging in VS 2013, otherwise it loads both extensions into my VS 2013 Experimental instance and I run into assembly version runtime errors; when opening my solution in VS 2012 is simply does not know how to load the VS 2013 project, so it does not have this problem.

    When I want to actually build my vsix files for release, I only need to build in VS 2013, as it will build both the VS 2012 and VS 2013 projects to their respective /bin/Release folders.

    Here is what my 2012 project's .csproj file looks like so that I can open the VS 2012 project in VS 2013 without it always prompting me to upgrade:

      <PropertyGroup>
        <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
        <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
        <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
      </PropertyGroup>
      <!-- This is the property that causes VS 2013+ to insist on one-way update of the project -->
      <PropertyGroup Condition="'$(VisualStudioVersion)' &gt;= '11.0'">
        <MinimumVisualStudioVersion>$(VisualStudioVersion)</MinimumVisualStudioVersion>
      </PropertyGroup>

    Thanks again to DanielKzu for his blog post!

    So now I have a single VS 2013 solution hosting my VS 2012 and VS 2013 VSPackage projects.

    If you want to look at my source code, again here is the link.


    - Dan - "Can't never could do anything"

    • Marked as answer by deadlydog Wednesday, March 12, 2014 6:02 PM
    Wednesday, March 12, 2014 6:02 PM
  • I posted this question on Daniel's blog, but for more visibility I'll repost it here...

    What about VSPackage Builder that currently only supports VS 2010? Is there a way to successfully open a VS 2010 project that uses VSPackage Builder in VS 2012/2013?

    Note that if VSPackage Builder doesn’t work in VS 2012/2013, that is fine, one can always re-open it in VS 2010 if you want to use the VSPackage Builder features. But I don’t want VS 2012/2013 blowing up because it doesn’t understand the VSPackage Builder files, or modifying the VSPackage Builder files so it no longer works when opening it again in VS 2010.

    Thursday, March 13, 2014 6:44 PM
  • Hi Daniel, my problem is almost the same as the thread opener. I created a VSPackage on 2013, and wants to make it compatible to 2010 and 2012.

    The differences is that I don't initially created it using 2012 and upgreaded to 2013, and don't intend to have one project for each version.

    I tried the recommended steps on your blog post and had no success, Don't worried about assembly locations for build server cause will not use one and have all SDKs installed on my machine.

    I think that maybe it didn't worked cause it would be needed to first create on VS2010, upgrade to 2012 and 2013.

    Theres any way I can make my 2013 built VSPackage compatible with 2010 and 2012?

    Sunday, March 23, 2014 3:43 PM
  • Hey fjcardoso, I'm pretty sure that all you need to do is add the following code to your .csproj file:

      <PropertyGroup>
        <MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
        <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
        <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
      </PropertyGroup>
      <!-- This is the property that causes VS 2012+ to insist on one-way update of the project -->
      <PropertyGroup Condition="'$(VisualStudioVersion)' &gt;= '10.0'">
        <MinimumVisualStudioVersion>$(VisualStudioVersion)</MinimumVisualStudioVersion>
      </PropertyGroup>

    Then you should be able to open the project in VS 2010, 2012, and 2013.

    From there you need to make sure that you aren't using any v11.0 or v12.0 references, as those will likely break at compile time since the VS 2010 SDK only has up to v10.0 assemblies.


    - Dan - "Can't never could do anything"

    Monday, March 24, 2014 9:22 PM