Making Sense of AssemblyVersion Numbers

,

The components of a Microsoft DLL or EXE version number are Major, Minor, Build and Revision. According to Microsoft, the components are used by convention as follows:

Major: Assemblies with the same name but different major versions are not interchangeable. A higher version number might indicate a major rewrite of a product where backward compatibility cannot be assumed.

Minor: If the name and major version number on two assemblies are the same, but the minor version number is different, this indicates significant enhancement with the intention of backward compatibility. This higher minor version number might indicate a point release of a product or a fully backward-compatible new version of a product.

Build: A difference in build number represents a recompilation of the same source. Different build numbers might be used when the processor, platform, or compiler changes.

Revision: Assemblies with the same name, major, and minor version numbers but different revisions are intended to be fully interchangeable. A higher revision number might be used in a build that fixes a security hole in a previously released assembly.

In the real world, version numbers mean different things to different people. However, when using Visual Studio and MSBuild, I tend to use Microsoft’s definition for Major and Minor, but Visual Studio’s automatic assignment for Build and Revision, where Build is defined as the number of days since January 1, 2000 and Revision is defined as the number seconds (divided by two) into the day on which the compilation was performed. The number of seconds must be divided by two since there are 86,400 seconds in a day and the maximum value of the Revision number is 65534 (yes, not 65535 which causes an error).

error 65535

Error generated by using 65535 as Build or Revision

A Personal Example

Recently I was told that an issue was found in a Windows service that I support, as of version 1.0.5876.25143. To find the changeset used to build that version, I only have timestamps to compare to.

changese and date

Changeset and Date, but no Version

Fortunately, in our AssemblyInfo.cs property file, we use the automatic version format, with an asterisk in the Build position.

The Build and Revision portions of the version are automatically set to the date and time as described above, so all I needed to do was convert the values.

  • Build 5876 is 5876 days after January 1, 2000; in this case, February 2, 2016.
  • Revision 25143 is one-half the number of seconds into the day; in this case 1:58:06 PM.

So I know that the changeset in question was 99119.

To make this easy to figure out, I wrote a simple console program to do the conversion. It simply takes a version number on the command line (with gross assumptions that it’s in the correct format), parses out the value using Version.Parse. It takes the Build number and adds that number of days to 1/1/2000, then adds twice the number of seconds as defined by the Revision number, and writes out the result as version elements and as a date and time.

 

Here is the program source.

Another Point

Besides setting the AssemblyVersion, I also remove the FileVersion setting. If FileVersion is specified then its value is used as-is even when the AssemblyVersion is automatically assigned. So if FileVersion is left as 1.0.0.0 then even though you’re setting the AssemblyVersion, your DLL or EXE will appear to be version 1.0.0.0. By removing it, the FileVersion will default to the AssemblyVersion. It is also important to note that FileVersion does not support automatic versioning so it must be either fully hard-coded or completely removed, as I suggest here.

versiontodate details

VersionToDate Properties/Details

 

Let’s Take It A Step Further

Now that we know how to decypher the version number, let’s look at making Assembly Versions a bit more useful. For instance, if your solution has a number of projects, you may want each DLL to have the same version so they can be easily associated with each other. You could do it the hard way and make sure you keep all of your AssemblyVersions the same in every AssemblyInfo.cs file. Or you could use a single shared AssemblyInfo.cs file so you only have to set one AssemblyVersion value.

To do this, copy or create an AssemblyInfo.cs file in the same folder as your solution file (or in Resources if you prefer). Create a Solution folder if you don’t already have one.

solutionfolder

Drag the new AssemblyInfo.cs file onto your Solution folder.

Screen Shot 2016-03-15 at 12.21.19 PM

Remove the AssemblyInfo.cs file from each of your projects, and for each one, right-click the project and select Add -> Existing Item.

Screen Shot 2016-03-15 at 12.21.39 PM

Find the common AssemblyInfo.cs file and select it, but rather than clicking Add, click the arrow next to Add and select Add As Link.

Screen Shot 2016-03-15 at 12.22.02 PM

The AssemblyInfo.cs file will drop into the project folder rather than into the Properties sub-folder. So just drag it onto Properties and you’re all set.

Screen Shot 2016-03-15 at 12.24.52 PM

Screen Shot 2016-03-15 at 12.25.01 PM

You will not see the AssemblyInfo.cs file in the Properties folder of your project. It only exists on disk in the one place you created it, which is why we keep a Solution  Folder reference to it.

Now whenever you change the version in the Solution copy of AssemblyInfo.cs (or any of the linked version, for that matter) all projects will have the same change.

Alternatively, if you have a project in which you still want to use a unique version number, but most others are shared, you just need to keep an actual AssemblyInfo.cs file in that project instead of a link to the shared one. That project will retain its specific version independent of the shared version.

Share this story

Leave a Reply

Your email address will not be published. Required fields are marked *