Обнаружить версию Visual Studio внутри VSPackage

Как я могу проверить/определить, какая версия Visual Studio работает под моим VSPackage?

Я не могу получить из реестра, потому что на компьютере может быть установлено несколько версий, поэтому я предполагаю, что есть API, который может его получить.

Кто-нибудь знает, как получить его из управляемого пакета Visual Studio с помощью С#?

Ответ 1

Наконец, я написал класс для обнаружения версии Visual Studio. Протестировано и работает:

public static class VSVersion
{
    static readonly object mLock = new object();
    static Version mVsVersion;
    static Version mOsVersion;

    public static Version FullVersion
    {
        get
        {
            lock (mLock)
            {
                if (mVsVersion == null)
                {
                    string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "msenv.dll");

                    if (File.Exists(path))
                    {
                        FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(path);

                        string verName = fvi.ProductVersion;

                        for (int i = 0; i < verName.Length; i++)
                        {
                            if (!char.IsDigit(verName, i) && verName[i] != '.')
                            {
                                verName = verName.Substring(0, i);
                                break;
                            }
                        }
                        mVsVersion = new Version(verName);
                    }
                    else
                        mVsVersion = new Version(0, 0); // Not running inside Visual Studio!
                }
            }

            return mVsVersion;
        }
    }

    public static Version OSVersion
    {
        get { return mOsVersion ?? (mOsVersion = Environment.OSVersion.Version); }
    }

    public static bool VS2012OrLater
    {
        get { return FullVersion >= new Version(11, 0); }
    }

    public static bool VS2010OrLater
    {
        get { return FullVersion >= new Version(10, 0); }
    }

    public static bool VS2008OrOlder
    {
        get { return FullVersion < new Version(9, 0); }
    }

    public static bool VS2005
    {
        get { return FullVersion.Major == 8; }
    }

    public static bool VS2008
    {
        get { return FullVersion.Major == 9; }
    }

    public static bool VS2010
    {
        get { return FullVersion.Major == 10; }
    }

    public static bool VS2012
    {
        get { return FullVersion.Major == 11; }
    }
}

Ответ 2

Вы можете попытаться получить версию через объект DTE автоматизации. В MPF вы можете получить его таким образом:

EnvDTE.DTE dte = (EnvDTE.DTE)Package.GetGlobalService(typeof(EnvDTE.DTE));

Есть некоторые другие связанные вещи для извлечения объекта DTE - через Project.DTE, также читайте этот поток, если вы получаете null для DTE.

Затем вы можете получить версию, используя свойство DTE.Version.

Также можно найти полезную информацию на веб-сайте Карлоса Кинтеро (VS addin ninja) HOWTO: обнаружение установленных версий, пакетов или пакетов обновления Visual Studio

Ответ 3

Я думаю, что следующий код лучше:

string version = ((EnvDTE.DTE) ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE.DTE).GUID)).Version;

Ответ 4

Чтобы получить полную семантическую версию, которая включает номера патчей, например "15.9.6", ни DTE.Version, ни версии файлов не дают достаточной информации.

Я нашел решение в новой системе управляемых проектов (https://github.com/dotnet/project-system), которая работает, по крайней мере, в VS2017.

По сути, он использует COM-интерфейс IVsAppId, который необходимо объявить, как в этом файле. (Вы можете скопировать этот файл как есть.)

После того, как вы это сделали, вам нужно получить реализацию IVsAppId обычным способом через поставщика услуг и вызвать метод GetProperty с помощью VSAPropID.VSAPROPID_ProductSemanticVersion (перечисление также определено в связанном файле):

var vsAppId = serviceProvider.GetService<IVsAppId>(typeof(SVsAppId));

vsAppId.GetProperty((int)VSAPropID.VSAPROPID_ProductSemanticVersion, out var semanticVersionObj);

semanticVersionObj в приведенном выше примере будет содержать строку в формате, подобном 15.9.6+28307.344. Получение части до + (иногда -) дает вам семантическую версию: 15.9.6.

Кстати: он используется в управляемой системе проектов здесь.

(Это так здорово, что MS сделала новый код системы проекта открытым исходным кодом. Он предоставляет хороший источник информации, а также вы можете найти в нем полезные шаблоны.)

Ответ 5

var shell = _package.GetService(typeof(SVsShell)) as IVsShell;
shell.GetProperty((int)__VSSPROPID5.VSSPROPID_ReleaseVersion, out object ver);
return ver.ToString();