Den AssemblyInformationalVersion-Wert der .NET-Assembly abrufen?

73

Wie lautet die C # -Syntax zum Abrufen des AssemblyInformationalVersionAttributwerts der Assembly zur Laufzeit? Beispiel:

[assembly: AssemblyInformationalVersion("1.2.3.4")]

Lanze
quelle

Antworten:

72
using System.Reflection.Assembly  
using System.Diagnostics.FileVersionInfo

// ...

public string GetInformationalVersion(Assembly assembly) {
    return FileVersionInfo.GetVersionInfo(assembly.Location).ProductVersion;
}
Lanze
quelle
8
Beachten Sie, dass dieser Code nicht funktioniert, wenn die Assembly nicht aus einer Datei oder einem UNC geladen wurde. Dies kann der Fall sein, wenn die Baugruppe in eine andere Baugruppe eingebettet ist (normalerweise beim Verschleiern von Baugruppen) oder aus einem anderen Grund mitAssembly.Load(byte[])
larsmoa
2
Funktioniert auch nicht, wenn Sie mkbundleIhre Bewerbung für Mono
Cocowalla
41
var attr = Assembly
    .GetEntryAssembly()
    .GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false) 
    as AssemblyInformationalVersionAttribute[];

Es ist eine Reihe von AssemblyInformationalVersionAttribute. Es ist niemals null, selbst wenn es kein Attribut des gesuchten Typs gibt.

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

Dies kann null sein, wenn das Attribut nicht vorhanden ist.

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

Gleich wie zuerst.

Xanatos
quelle
1
+1; Sie können jedoch GetCustomAttributeanstelle von verwenden, GetCustomAttributeswenn Sie wissen, dass es nur ein Attribut gibt.
vcsjones
3
@vcsjones Nur mit der statischen Methode von Attribute, nicht mit der Instanzmethode vonAssembly
xanatos
1
In einigen Situationen Assembly.GetEntryAssembly()sollte durch Assembly.GetExecutingAssembly()oder ersetzt werden Assembly.GetCallingAssembly(). In der Regel ist dies erforderlich, wenn es sich bei der Assembly um ein Plugin handelt. In diesem Fall GetEntryAssembly()wird die Assembly der Hostanwendung zurückgegeben.
Larsmoa
20

Mit einem bekannten Typ in Ihrer Anwendung können Sie dies einfach tun:

using System.Reflection;

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

Natürlich ist jeder Prozess, mit dem Sie zu der Assembly gelangen, auf die Ihr Attribut angewendet wird, gut. Beachten Sie, dass dies nicht vom System.Diagnosticsoder dem WinForm- ApplicationObjekt abhängt .

Robb Vandaveer
quelle
12

Auch wenn die Frage etwas alt ist:

Ich schlage eine andere Lösung vor, die für mich funktioniert:

Application.ProductVersion
Wollnyst
quelle
7
Es fiel mir schwer, es in WPF zu finden. Es ist die Winforms-Anwendungsklasse. :-)
Wouter
1
Gibt es einen Grund, diese Variante nicht zu verwenden? Im Vergleich dazu sehen alle anderen Antworten kompliziert aus.
Rev1.0
2
@ Rev1.0 Wenn Sie WinForms nicht anderweitig nutzen, laden Sie> 5 Megabyte in den RAM, nur um es dem Programmierer bequem zu machen.
tm1
9
AssemblyInformationalVersionAttribute attribute = 
   (AssemblyInformationalVersionAttribute)Assembly.GetExecutingAssembly()
   .GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false).FirstOrDefault();

if (attribute != null)
     Console.WriteLine(attribute.InformationalVersion);
DeCaf
quelle
+1, da dies auch mit Silverlight oder Xbox Lakeview funktioniert!
Ahilsend
6

Um die Antwort von Lance zu ergänzen: Sie können Application.ResourceAssembly.Locationden Dateipfad Ihrer Baugruppe ermitteln. Damit ist es möglich, die AssemblyInformationalVersion-Zeichenfolge in nur einer Zeile abzurufen

System.Diagnostics.FileVersionInfo.GetVersionInfo(Application.ResourceAssembly.Location).ProductVersion
Aerthel
quelle
0

Aufbauend auf der Antwort von @ Aerthal, wenn Sie möchten, dass ein Einzeiler das AssemblyInformationalVersionAttribute aus einer MVC Razor-Ansicht erhält:

@System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(Zeroarc.Candid.Web.MvcApplication).Assembly.Location).ProductVersion
jslatts
quelle
0

Ein praktischer Ansatz

Da das Abrufen des Datums aus dem PE-Header möglicherweise nicht zuverlässig genug ist, können Sie Ihrem Attribut zusätzliche Attribute hinzufügen AssemblyInfo.cs

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

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

Die Zeichenfolge sollte lesbar sein, da sie für den Endbenutzer sichtbar ist. Wenn Sie sich jedoch an ein bestimmtes Format halten, kann es einfach und zuverlässig analysiert werden .

Hinweis: Wir verwenden einen Jenkins-Buildserver, der Versionsinformationen AssemblyInfo.cszusammen mit der Datumszeichenfolge in die Datei schreibt .

Geben Sie hier die Bildbeschreibung ein

Bytecode77
quelle
0
public static string GetInformationalVersion() =>
    Assembly
        .GetEntryAssembly()
        .GetCustomAttribute<AssemblyInformationalVersionAttribute>()
        .InformationalVersion;

Obwohl meine Antwort einigen der anderen ähnlich ist, denke ich, dass sie einige Vorteile hat:

  • Es bestimmt die Informationsversion der Eintragsbaugruppe. Das bedeutet, dass sich dieser Code in einer Bibliothek in einem größeren Projekt befinden kann und dennoch die Version des "Programms, auf das der Benutzer doppelt geklickt hat" erhält, ohne dass eine Abhängigkeit besteht.
    • Wenn Sie die Version der Assembly zu erhalten , dass der Code befindet (dh der Bibliothek nicht das Hauptprogramm) Sie ersetzen können GetEntryAssembly()mitGetExecutingAssembly()
  • Die Informationsversion wird nicht anhand einer Datei ermittelt. Die E / A-Operation ist nicht erforderlich und in einigen Fällen sogar unmöglich (ich denke an einige Methoden zum Packen einzelner Dateien, AoT-Varianten, Software, die über UNC-Pfade ausgeführt wird usw.).
  • Es teilt die beiden oben genannten Aspekte mit der Antwort von @xanatos, aber ich verwende die generische Erweiterungsmethode GetCustomAttribute<T>besser und denke, dass diese Variante besser lesbar ist.

Siehe auch Microsoft Docs onGetCustomAttribute<T>(Assembly) .

Georg Jung
quelle