How to package a VSIX-based extension for multiple Visual Studio versions?
Asked Answered
P

2

11

I am maintaining a company internal Visual Studio extension that is packaged and deployed as VSIX container. This extension currently targets VS 2010. It uses several VS API DLLs and references the VS 2010 versions of them.

I am currently migrating this extension to be compatible with VS 2012/2013. I already found out that the old VSIX manifest can be edited manually to allow the extension to additionally install to VS 2012/2013 - this works perfectly.

However some of the VS 2010 APIs I am currently using are not compatible with VS 2012++ and I need to update them - with the effect of giving up backward compatibility.

My question is: How should I structure my solution and VSIX so that It will be compatible with VS 2010, 2012 and 2013. Would it work to have one DLL targeting VS 2010 and one DLL targeting VS 2012/2013 and picking the one to use at extension load time?

Side note: I am using MEF to compose my internal functional units. Does that make it easier in any way?

Piffle answered 26/11, 2013 at 10:42 Comment(2)
Good question, I would like have an answer to that too!Roomette
As far as I've researched, it is not possible via manifest file. It may be possible to do it by code but I don't think it is feasible.Horseback
S
6

You may:

  1. decouple the functionality exposed by the two version-specific assemblies into an ad-hoc interface (which you can put itself into the host assembly, if you wish), as you may do with every other MEF plugin; let's call it IDoWork;
  2. implement the aforementioned interface in two concrete types, exposed by two different assemblies, one for each VS version you are supporting, e.g. DoWorkVs2010 and DoWorkVs2012;

    • AssemblyForVS2010.dll -> DoWorkVs2010 : IDoWork
    • AssemblyForVS2012.dll -> DoWorkVs2012 : IDoWork

. 3. (optional) [Export] the two types, to make them available through MEF; e.g.:

    [Export(typeof(IDoWork))]
    class DoWorkVs2010 : IDoWork
    {
        // ...
    }

4. add a factory to your host assembly (the one loaded directly with your VSX) and, from there, build the concrete type you are looking for, based on the DTE version:

    static class DoWorkFactory
    {
        internal static IDoWork Build()
        {
            // Load the version-specific assembly

            // - Via reflection (see https://mcmap.net/q/135101/-can-i-load-a-net-assembly-at-runtime-and-instantiate-a-type-knowing-only-the-name)
            // - Or via MEF

            return ...;
        }
    }
Selfish answered 3/12, 2013 at 21:46 Comment(1)
Thank you Efran. I thought there'd be an easier way to achieve this, but I got it running using an approach very similar to the one you describe.Piffle
C
0

Use these VSIX templates from Jared Par. They're developed with the express purpose of making your VSIX project installable and openable in multiple VS versions. It looks like they might need a freshen up for VS2015, but they're definitely the place to start for most VSIX development.

Curator answered 2/6, 2016 at 14:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.