What is the C# syntax for getting the assembly's AssemblyInformationalVersion
attribute value at runtime? Example:
[assembly: AssemblyInformationalVersion("1.2.3.4")]
using System.Reflection.Assembly
using System.Diagnostics.FileVersionInfo
// ...
public string GetInformationalVersion(Assembly assembly) {
return FileVersionInfo.GetVersionInfo(assembly.Location).ProductVersion;
}
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.
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.
Even if the question is a bit old:
I propose a different solution that works for me:
Application.ProductVersion
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:
GetEntryAssembly()
with GetExecutingAssembly()
GetCustomAttribute<T>
better and think this variant is more readable.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;
AssemblyInformationalVersionAttribute attribute =
(AssemblyInformationalVersionAttribute)Assembly.GetExecutingAssembly()
.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false).FirstOrDefault();
if (attribute != null)
Console.WriteLine(attribute.InformationalVersion);
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
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
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.
http://msdn.microsoft.com/en-us/library/system.reflection.assemblyinformationalversionattribute.aspx
Take a look at the InformationalVersion property