Detect the Visual Studio version inside a VSPackage
I think the following code is better:
string version = ((EnvDTE.DTE) ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE.DTE).GUID)).Version;
You could try to get version via automation DTE object. In MPF you could get it in this way:
EnvDTE.DTE dte = (EnvDTE.DTE)Package.GetGlobalService(typeof(EnvDTE.DTE));
There are some other related things to retrieve DTE object - via Project.DTE, also read this thread if you're getting null for DTE.
Then you can get the version by using DTE.Version property.
Also useful information could be found on Carlos Quintero (VS addin ninja) website HOWTO: Detect installed Visual Studio editions, packages or service packs
To get the full semantic version that includes the patch numbers, like "15.9.6", neither DTE.Version
nor the file versions give sufficient information.
I have found a solution in the new managed project system (https://github.com/dotnet/project-system) that seems to be working in VS2017 at least.
Basically, it is using the IVsAppId
COM interface, that you need to declare, like in this file. (You can basically copy that file as it is.)
Once you did that, you need to get the IVsAppId
implementation in the usual way through a service provider, and call the GetProperty
method with VSAPropID.VSAPROPID_ProductSemanticVersion
(the enum is also defined in the linked file):
var vsAppId = serviceProvider.GetService<IVsAppId>(typeof(SVsAppId));
vsAppId.GetProperty((int)VSAPropID.VSAPROPID_ProductSemanticVersion, out var semanticVersionObj);
The semanticVersionObj
in the sample above will contain a string, in format, like 15.9.6+28307.344
. Getting the part before +
(sometimes -
) gives you the semantic version: 15.9.6
.
BTW: it is used in the managed project system here.
(It is so great that MS made the new project system code open source. It provides a good source of information and also you can find useful patterns in it.)
Finally I wrote a class to detect the Visual Studio version. Tested and working:
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; }
}
}