88

What is the C# syntax for getting the assembly's AssemblyInformationalVersion attribute value at runtime? Example:

[assembly: AssemblyInformationalVersion("1.2.3.4")]

Charles
  • 50,943
  • 13
  • 104
  • 142
lance
  • 16,092
  • 19
  • 77
  • 136

10 Answers10

83
using System.Reflection.Assembly  
using System.Diagnostics.FileVersionInfo

// ...

public string GetInformationalVersion(Assembly assembly) {
    return FileVersionInfo.GetVersionInfo(assembly.Location).ProductVersion;
}
Michael Haren
  • 105,752
  • 40
  • 168
  • 205
lance
  • 16,092
  • 19
  • 77
  • 136
  • 11
    Note that this code does not work if the assembly has not been loaded from file or an UNC. This could be the case if the assembly is embedded in another assembly (typically when obfuscating assemblies) or for some other reason has been loaded using `Assembly.Load(byte[])` – larsmoa Sep 26 '13 at 18:52
  • 2
    Also doesn't work if you've `mkbundle`'d your application for Mono – Cocowalla Apr 29 '14 at 21:49
47
var attr = Assembly
    .GetEntryAssembly()
    .GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false) 
    as AssemblyInformationalVersionAttribute[];

It's an array of AssemblyInformationalVersionAttribute. It isn't ever null even if there are no attribute of the searched type.

var attr2 = Attribute
    .GetCustomAttribute(
        Assembly.GetEntryAssembly(), 
        typeof(AssemblyInformationalVersionAttribute)) 
    as AssemblyInformationalVersionAttribute;

This can be null if the attribute isn't present.

var attr3 = Attribute
    .GetCustomAttributes(
         Assembly.GetEntryAssembly(), 
         typeof(AssemblyInformationalVersionAttribute)) 
    as AssemblyInformationalVersionAttribute[];

Same as first.

xanatos
  • 109,618
  • 12
  • 197
  • 280
  • 1
    +1; but you can use `GetCustomAttribute` instead of `GetCustomAttributes` if you know that there will only be one attribute. – vcsjones Oct 14 '11 at 15:49
  • 3
    @vcsjones Only by using the static method of `Attribute`, not using the instance method of `Assembly` – xanatos Oct 14 '11 at 15:53
  • 1
    In some situations, `Assembly.GetEntryAssembly()` should be replaced by `Assembly.GetExecutingAssembly()` or `Assembly.GetCallingAssembly()`. Typically this is necessary if the assembly is a plugin - in this case `GetEntryAssembly()` will return the host application assembly. – larsmoa Sep 26 '13 at 19:09
21

Using a known type in your application you can simply do this:

using System.Reflection;

public static readonly string ProductVersion = typeof(MyKnownType).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;

Of course any process you use to get to the assembly your attribute is applied to is good. Note that this doesn't rely on System.Diagnostics or the WinForm's Application object.

Robb Vandaveer
  • 1,481
  • 20
  • 25
13

Even if the question is a bit old:

I propose a different solution that works for me:

Application.ProductVersion
wollnyst
  • 1,683
  • 1
  • 17
  • 20
  • 7
    I had a hard time finding it in WPF, it is the Winforms Application class. :-) – Wouter Oct 10 '13 at 08:21
  • 1
    Is there any reason not use this variant? Compared to this, all the other answers look over complicated. – Rev Sep 26 '18 at 08:26
  • 2
    @Rev1.0 if you don't otherwise leverage WinForms, you're loading > 5 Megs into RAM just for programmer's convenience. – tm1 Sep 26 '19 at 06:41
12
public static string? GetInformationalVersion() =>
    Assembly
        .GetEntryAssembly()
        ?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
        ?.InformationalVersion;

While my answer is similar to some of the others, I think it has some advantages:

  • It determines the informational version of the entry assembly. That means this code can reside in a library in a bigger project and still get's the version of the "program the user has double clicked" without taking any dependency.
    • If you want to get the version of the assembly that the code resides in (i.e. the library not the main program) you can replace GetEntryAssembly() with GetExecutingAssembly()
  • It doesn't determine the informational version by looking at a file. The I/O operation is unneeded and even impossible in some cases (I'm thinking of some single file packaging methods, AoT variants, software executed from UNC paths, etc).
  • It shares the above two aspects with @xanatos' answer, however I like using the generic extension method GetCustomAttribute<T> better and think this variant is more readable.
  • Update 2023-01-04: Added null propagation and support for nullable reference types.

See also the Microsoft Docs on GetCustomAttribute<T>(Assembly).


Note that in illink/AoT scenarios like MAUI Android this might return null. If you're using an automatic versioning solution, there might be additional reflection-free ways to get the version information. If you are, for example, using Nerdbank.GitVersioning, you could use

public static string? GetInformationalVersion() =>
    ThisAssembly.AssemblyInformationalVersion;
Georg Jung
  • 949
  • 10
  • 27
11
AssemblyInformationalVersionAttribute attribute = 
   (AssemblyInformationalVersionAttribute)Assembly.GetExecutingAssembly()
   .GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false).FirstOrDefault();

if (attribute != null)
     Console.WriteLine(attribute.InformationalVersion);
DeCaf
  • 6,026
  • 1
  • 29
  • 51
6

To complement lance's answer: You can use Application.ResourceAssembly.Location to find out the file path of your assembly. With this it's possible to get the AssemblyInformationalVersion string in just one line

System.Diagnostics.FileVersionInfo.GetVersionInfo(Application.ResourceAssembly.Location).ProductVersion
Aerthel
  • 659
  • 8
  • 8
0

Building off of @Aerthal's answer, if you want a one liner to get the AssemblyInformationalVersionAttribute from a MVC Razor View:

@System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(Zeroarc.Candid.Web.MvcApplication).Assembly.Location).ProductVersion
jslatts
  • 9,307
  • 5
  • 35
  • 38
0

A practical approach

Given that retrieving the date from the PE header may not be reliable enough, there is a way to include additional attributes to your AssemblyInfo.cs

[assembly: AssemblyVersion("1.0.0")]
[assembly: AssemblyFileVersion("1.0.0")]

// and this:
[assembly: AssemblyInformationalVersion("1.0.0 (Build Date: 14.07.2020)")]

The string should be readable, because it is visible to the end user. But if you stick to a specific format, it can be parsed with ease and reliability.

Note: We are using a Jenkins build server, which writes version info into the AssemblyInfo.cs along with the date string.

enter image description here

bytecode77
  • 14,163
  • 30
  • 110
  • 141
0

http://msdn.microsoft.com/en-us/library/system.reflection.assemblyinformationalversionattribute.aspx

Take a look at the InformationalVersion property

mrK
  • 2,208
  • 4
  • 32
  • 46
  • 2
    That gets the version defined by the `AssemblyVersionAttribute`, not `AssemblyInformationalVersionAttribute`. – vcsjones Oct 14 '11 at 15:46