Visual Studio extensions and version ranges demystified
Extension authors use visual Studio version ranges to specify what versions of Visual Studio their extensions support. A version range looks like this [14.0, 17.0) and specifies the minimum and maximum version of Visual Studio as well as if the edges are included or excluded. The syntax with mismatching braces may initially seem a bit odd and what exactly do those numbers refer to? Let’s unravel the mystery of the Visual Studio version ranges.
Let’s start by separating the version of Visual Studio from its name which can be a bit confusing. The 10th version of Visual Studio was released in the year 2010 and was given the name Visual Studio 2010. The fact that version 10.0 of Visual Studio was released in 2010 was coincidental, and made it seem like the version number followed the year of its release and therefore its name. Here’s a list of versions and names to illustrate how coincidental it was:
|8.0||Visual Studio 2005|
|9.0||Visual Studio 2008|
|10.0||Visual Studio 2010|
|11.0||Visual Studio 2012|
|12.0||Visual Studio 2013|
|14.0||Visual Studio 2015|
|15.0||Visual Studio 2017|
|16.0||Visual Studio 2019|
If Visual Studio continues to follow a release cadence of roughly every 2 years, then there will never again be a version that matches its name. Version 113.0 in the year 2213 will be the closest match.
You may be wondering why version 13.0 was skipped or attribute it to being an unlucky number in some cultures. That’s what I always thought, but then I started asking around and it turns out I was wrong. The real reason for skipping 13.0 was the believe that it would be confused with Visual Studio 2013 which was the current latest version at the time. Whether or not it made things less confusing in the end is up to you to decide.
In an extension that supports version 14.0, 15.0 and 16.0 of Visual Studio, express the version range like this [14.0, 17.0). Let’s break it down into its subparts.
It starts with a square bracket meaning edge inclusive which is then followed by 14.0. Let’s call this the from-part of the version range. You can read it like from and including version 14.0.
The last part is called the to-part and consists of the version number 17.0 followed by a parenthesis. A parenthesis means edge exclusive and will therefore not include the 17.0 version number. It can be read like up to, but not including version 17.0.
The entire version range [14.0, 17.0) therefore means from, and including version 14.0 – up to, but not including version 17.0. This version range syntax was introduced in Visual Studio 2015 (version 14.0).
Updates and minor versions
When an update to Visual Studio 2017 is shipped, it maintains its major and minor version, but the build and revision numbers change.
For instance, the full version of Visual Studio 2017 version 15.1 was 15.0.26403.0. Get the version numbers from this full list of Visual Studio versions and replace the minor version with 0 if you need to use it in an extension’s version range.
An extension can use an API introduced in version 15.1 but should make sure it can’t be installed on older versions to avoid runtime errors. To do that, the version range must reflect the build number of version 15.1 and could look like [15.0.26403, 17.0).
Visual Studio 2019
Why not just write 15.1 instead of 15.0.26403? In Visual Studio 2017 and earlier, this was due to an implementation detail and we therefore had to keep a 0 as the minor version and write out the long build number. In Visual Studio 2019 we can finally start using the minor version and forget about the build number. As of this writing, the are no updates released for Visual Studio 2019, but we will be able to write version ranges like [16.1, 17.0).
Let’s imagine that I wrote an extension with a feature that users have been asking the Visual Studio team to build into the official product. Finally, they release the feature as part of an update to Visual Studio 2019. Now I must make sure my extension cannot be installed in that version to avoid the two similar features from colliding. To do that, I would update the version range to be something like [14.0, 16.1) to express that from version 16.1 and beyond the extension isn’t supported.
Since minor version numbers are supported in version ranges in Visual Studio 2019, it means that the old syntax for specifying versions should no longer be used. The old syntax was one that didn’t have both a from and a to-part and was a simple version string like 16.0. That syntax is now interpreted as only version 16.0 by Visual Studio 2019 and doesn’t include any future updates such as 16.1.
To correctly specify a version range supporting version 16.0 including all its updates, the version range to use is [16.0, 17.0).
What if you want to specify that an extension should be supported by version 14.0 and all version of Visual Studio that will ever be released after that? Express that by omitting the to-part like [14.0,) which is known as an open-ended version range. However, we strongly discourage using open-ended versioning since it is considered a bad practice. In fact, soon you won’t be able to upload extensions with open-ended version ranges to the Marketplace.
There is no way of knowing that an extension will work in all future versions of Visual Studio. It probably won’t and will eventually cause a runtime error in that future version. Where open-ended version ranges are useful is when specifying dependencies and prerequisites. If my extension supports [15.0, 17.0) and has a dependency on a component that exist in all versions, then it makes good sense to write something like this in the .vsixmanifest file:
<Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[15.0,)" />
What version to support
In a perfect world, an extension would only support the very latest release of Visual Studio to take advantage of the latest and greatest APIs. Unfortunately, not all Visual Studio users update to the latest version as soon as it is released. It is also easier to code, test and maintain extensions targeting as few versions of Visual Studio as possible.
So how many versions back does it make sense to support? What is the right balance of ease of coding and reaching as many potential users as possible?
To answer that question, we need to know the distribution of extension users using each version of Visual Studio. Today, over 95% of all extension users are on Visual Studio 2015 (14.0) or newer. So, if I were to write an extension today, I would target [14.0, 17.0).
I hope this helped clear up how the versioning works. If not, let me know in the comments.