16

如何检查/检测在我的 VSPackage 下运行的 Visual Studio 版本?

我无法从注册表中获取,因为计算机可能安装了多个版本,所以我想有一个 API 可以获取它。

有人知道如何使用 C# 从托管的 Visual Studio 包中获取它吗?

4

6 回答 6

17

您可以尝试通过自动化 DTE 对象获取版本。在 MPF 中,您可以通过以下方式获得它:

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

还有一些其他相关的东西可以检索 DTE 对象 - 通过Project.DTE ,如果您为 DTE 获得空值,也请阅读此线程。

然后您可以使用DTE.Version 属性获取版本。

也可以在 Carlos Quintero (VS addin ninja) 网站HOWTO: Detect installed Visual Studio editions, packages or service packs上找到有用的信息

于 2012-06-18T15:00:51.917 回答
10

最后我写了一个类来检测 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; }
    }
}
于 2012-06-19T08:32:58.177 回答
2

我认为以下代码更好:

string version = ((EnvDTE.DTE) ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE.DTE).GUID)).Version;
于 2013-02-17T05:00:36.327 回答
2

要获得包含补丁号的完整语义版本,例如“15.9.6”,DTE.Version文件版本和文件版本都没有提供足够的信息。

我在新的托管项目系统(https://github.com/dotnet/project-system)中找到了一个解决方案,该解决方案似乎至少在 VS2017 中有效。

基本上,它使用的IVsAppId是您需要声明的 COM 接口,就像在这个文件中一样。(您基本上可以按原样复制该文件。)

一旦你这样做了,你需要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 将新项目系统代码开源真是太好了。它提供了很好的信息来源,您还可以在其中找到有用的模式。)

于 2019-03-07T09:11:32.977 回答
1

@gaspar-nagy 答案提供了最精确的版本。但是,它可以进一步增强。就像您需要添加IVsAppId/SVsAppId接口声明的答案建议一样,获取版本的代码也几乎相同。但是,您需要使用VSAPROPID_ProductDisplayVersion枚举值而不是VSAPROPID_ProductSemanticVersion来自VSAPropID枚举:

var vsAppId = serviceProvider.GetService<IVsAppId>(typeof(SVsAppId));
vsAppId.GetProperty((int)VSAPropID.VSAPROPID_ProductDisplayVersion, out var versionObj);

我的 VS 16.9.4 的 @gaspar-nagy 答案的语义版本是“16.9.4+31205.134”,需要进一步解析。但是这个显示版本是用户友好的,它的版本是“16.9.4”。

UPDATE: One important thing I've discovered recently is that in case of preview VS the version string in my answer will look something like 16.11.0 Preview 3.0. It may be important if you pass the obtained raw version string without any extra processing to some other APIs like System.Version constructor.

于 2021-05-10T19:55:29.730 回答
0
var shell = _package.GetService(typeof(SVsShell)) as IVsShell;
shell.GetProperty((int)__VSSPROPID5.VSSPROPID_ReleaseVersion, out object ver);
return ver.ToString();
于 2019-10-07T09:25:54.497 回答