We can define versions on our .NET Core applications, but how to get the version at runtime? There are several ways to do it.

First, let's look at a typical .NET Core project file with versioning. We can define the version numbers for AssemblyVersionFileVersion and Version in the project file (.csproj).

The AssemblyVersion and FileVersion attributes must be in format of "major[.minor[.build[.revision]]]" or you will get a compile time error (CS7034).

The attribute Version can contain customized strings, like a surfix of "-xyz" as shown below:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <AssemblyVersion>1.1.1.1</AssemblyVersion>
    <FileVersion>2.2.2.2</FileVersion>
    <Version>3.3.3.3-xyz</Version>
  </PropertyGroup>
</Project>

In compile time, this will generate a class file:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Reflection;

[assembly: System.Reflection.AssemblyCompanyAttribute("netcoreappver")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("2.2.2.2")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("3.3.3.3-xyz")]
[assembly: System.Reflection.AssemblyProductAttribute("netcoreappver")]
[assembly: System.Reflection.AssemblyTitleAttribute("netcoreappver")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.1.1.1")]

// Generated by the MSBuild WriteCodeFragment class.

With this in mind, let's see how we can read these values in runtime.

AssemblyVersion


There are two ways to get the AssemblyVersion

If you are not getting this in a static method, you can use 

GetType().Assembly.GetName().Version.ToString()

But if you need to use this in a static method, you may have to create a class like this:

class Foo
{
    public string GetAssemblyVersion()
    {
        return GetType().Assembly.GetName().Version.ToString();
    }
}

and then:

new Foo().GetAssemblyVersion()

This is ugly code. So we have another way to read the AssemblyVersion

Assembly.GetEntryAssembly().GetName().Version

This can be used in static and non-static methods.

Both two methods will return 1.1.1.1

FileVersion


We can use GetCustomAttribute extension method to get the AssemblyFileVersionAttribute and read the Version attribute.

Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version

It will return 2.2.2.2

Version


Like FileVersion but this time we will use AssemblyInformationalVersionAttribute

Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion

It will return 3.3.3.3

Complete Sample Code


using System;
using System.Reflection;

namespace netcoreappver
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"GetType().Assembly.GetName().Version: " +
                              $"{new Foo().GetAssemblyVersion()}");

            Console.WriteLine($"Assembly.GetEntryAssembly().GetName().Version: " +
                              $"{Assembly.GetEntryAssembly().GetName().Version}");

            Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version:" +
                              $"{Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version}");

            Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion:" +
                              $"{Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute> ().InformationalVersion}");

            Console.ReadKey();
        }
    }

    class Foo
    {
        public string GetAssemblyVersion()
        {
            return GetType().Assembly.GetName().Version.ToString();
        }
    }
}

Which version should I use?


According to this thread:

AssemblyVersion

Where other assemblies that reference your assembly will look. If this number changes, other assemblies must update their references to your assembly.

AssemblyFileVersion

Used for deployment. You can increase this number for every deployment. It is used for setup programs. Use it to mark assemblies that have the same AssemblyVersion, but are generated from different builds.

In Windows, it can be viewed in the file properties.

If possible, let it be generated by MSBuild. The AssemblyFileVersion is optional. If not given, the AssemblyVersion is used.

I use the format: major.minor.revision.build, where I use revision for development stage (Alpha, Beta, RC, and RTM), service packs and hot fixes. 

AssemblyInformationalVersion

The Product version of the assembly. This is the version you would use when talking to customers or for display on your website. This version can be a string, like '1.0 Release Candidate'.