it-swarm-eu.dev

Was sind die Unterschiede zwischen AssemblyVersion, AssemblyFileVersion und AssemblyInformationalVersion?

Es gibt drei Assemblyversionsattribute. Was sind Unterschiede? Ist es in Ordnung, wenn ich AssemblyVersion verwende und den Rest ignoriere?


MSDN sagt:

  • AssemblyVersion :

    Gibt die Version der Assembly an, die zugeordnet wird.

  • AssemblyFileVersion :

    Weist einen Compiler an, eine bestimmte Versionsnummer für die Win32-Dateiversionsressource zu verwenden. Die Win32-Dateiversion muss nicht mit der Versionsnummer der Assembly übereinstimmen.

  • AssemblyInformationalVersion :

    Definiert zusätzliche Versionsinformationen für ein Assembly-Manifest.


Dies ist eine Fortsetzung von Was sind die Best Practices für die Verwendung von Assembly-Attributen?

833
Jakub Šturc

AssemblyVersion

Wo andere Assemblys, die auf Ihre Assembly verweisen, suchen. Wenn sich diese Zahl ändert, müssen andere Baugruppen ihre Verweise auf Ihre Baugruppe aktualisieren! Das AssemblyVersion ist erforderlich.

Ich benutze das Format: major.minor. Dies hätte zur Folge:

[Assembly: AssemblyVersion("1.0")]

AssemblyFileVersion

Wird für die Bereitstellung verwendet. Sie können diese Anzahl für jede Bereitstellung erhöhen. Es wird von Setup-Programmen verwendet. Verwenden Sie diese Option, um Assemblys zu markieren, die dasselbe AssemblyVersion aufweisen, jedoch aus verschiedenen Builds generiert wurden.

In Windows kann es in den Dateieigenschaften angezeigt werden.

Wenn möglich, lassen Sie es von MSBuild generieren. Die AssemblyFileVersion ist optional. Wenn nicht angegeben, wird die AssemblyVersion verwendet.

Ich verwende das Format: major.minor.revision.build, wobei ich die Revision für die Entwicklungsphase (Alpha, Beta, RC und RTM), Service Packs und Hotfixes verwende. Dies hätte zur Folge:

[Assembly: AssemblyFileVersion("1.0.3100.1242")]

AssemblyInformationalVersion

Die Produktversion der Assembly. Dies ist die Version, die Sie verwenden würden, wenn Sie mit Kunden sprechen oder auf Ihrer Website anzeigen. Diese Version kann ein String sein, wie ' 1.0 Release Candidate'.

Die Code-Analyse wird sich darüber beschweren (CA2243) - an Microsoft gemeldet (nicht in VS2013 behoben).

Das AssemblyInformationalVersion ist optional. Wenn nicht angegeben, wird die AssemblyFileVersion verwendet.

Ich benutze das Format: major.minor [Revision als String]. Dies hätte zur Folge:

[Assembly: AssemblyInformationalVersion("1.0 RC1")]
885

Die Versionierung von Assemblys in .NET kann verwirrend sein, da es derzeit mindestens drei Möglichkeiten gibt, eine Version für Ihre Assembly anzugeben.

Hier sind die drei wichtigsten versionsbezogenen Assembly-Attribute:

// Assembly mscorlib, Version 2.0.0.0
[Assembly: AssemblyFileVersion("2.0.50727.3521")]
[Assembly: AssemblyInformationalVersion("2.0.50727.3521")]
[Assembly: AssemblyVersion("2.0.0.0")]

Standardmäßig werden die vier Teile der Version als Hauptversion , Nebenversion , ) bezeichnet Erstellen Sie und Revision .

Das AssemblyFileVersion soll einen Build der individuellen Assembly eindeutig identifizieren

In der Regel legen Sie die Haupt- und Neben-Assembly-Dateiversion manuell fest, um die Version der Assembly widerzuspiegeln, und erhöhen dann den Build und/oder die Revision jedes Mal, wenn Ihr Build-System die Assembly kompiliert. Die AssemblyFileVersion sollte es Ihnen ermöglichen, einen Build der Assembly eindeutig zu identifizieren, damit Sie ihn als Ausgangspunkt für das Debuggen von Problemen verwenden können.

In meinem aktuellen Projekt hat der Build-Server die Änderungslistennummer aus unserem Quellcodeverwaltungs-Repository in die Build- und Revision-Teile der AssemblyFileVersion codiert. Auf diese Weise können wir für jede vom Build-Server generierte Assembly direkt eine Zuordnung von einer Assembly zu ihrem Quellcode vornehmen (ohne Labels oder Zweige in der Quellcodeverwaltung verwenden oder manuell Aufzeichnungen über freigegebene Versionen führen zu müssen).

Diese Versionsnummer ist in der Win32-Versionsressource gespeichert und wird auf den Windows Explorer-Eigenschaftenseiten für die Assembly angezeigt.

Die CLR kümmert sich nicht um die AssemblyFileVersion und untersucht sie auch nicht.

Das AssemblyInformationalVersion soll die Version Ihres gesamten Produkts darstellen

Die AssemblyInformationalVersion soll eine kohärente Versionierung des gesamten Produkts ermöglichen. Diese kann aus vielen Assemblys bestehen, die unabhängig voneinander versioniert werden, möglicherweise mit unterschiedlichen Versionsrichtlinien, und möglicherweise von unterschiedlichen Teams entwickelt werden.

„Beispielsweise kann Version 2.0 eines Produkts mehrere Assemblys enthalten. Eine dieser Assemblys ist als Version 1.0 gekennzeichnet, da es sich um eine neue Assembly handelt, die nicht in Version 1.0 desselben Produkts geliefert wurde. In der Regel legen Sie die Haupt- und Nebenteile dieser Versionsnummer so fest, dass sie die öffentliche Version Ihres Produkts darstellen. Dann erhöhen Sie die Build- und Revisionsteile jedes Mal, wenn Sie ein komplettes Produkt mit all seinen Baugruppen verpacken. “- Jeffrey Richter, [CLR via C # (Second Edition)], S. 34. 57

Die CLR kümmert sich nicht um die AssemblyInformationalVersion und untersucht sie auch nicht.

Die AssemblyVersion ist die einzige Version, um die sich die CLR kümmert (aber sie kümmert sich um die gesamte AssemblyVersion)

Die AssemblyVersion wird von der CLR zum Binden an Assemblys mit starkem Namen verwendet. Es wird in der AssemblyDef-Manifest-Metadatentabelle der erstellten Assembly und in der AssemblyRef-Tabelle aller Assemblys gespeichert, die darauf verweisen.

Dies ist sehr wichtig, da Sie beim Verweisen auf eine Assembly mit starkem Namen eng an eine bestimmte AssemblyVersion dieser Assembly gebunden sind. Die gesamte AssemblyVersion muss exakt übereinstimmen, damit die Bindung erfolgreich ist. Wenn Sie zum Beispiel während der Erstellung auf Version 1.0.0.0 einer Assembly mit starkem Namen verweisen, aber nur Version 1.0.0.1 dieser Assembly zur Laufzeit verfügbar ist, schlägt die Bindung fehl! (Sie müssen dies dann mit Assembly Binding Redirection umgehen.)

Verwirrung darüber, ob das gesamte AssemblyVersion übereinstimmen muss. (Ja tut es.)

Es besteht ein wenig Verwirrung darüber, ob die gesamte AssemblyVersion exakt übereinstimmen muss, damit eine Assembly geladen werden kann. Einige Menschen sind der falschen Überzeugung, dass nur die Haupt- und Nebenteile der AssemblyVersion übereinstimmen müssen, damit die Bindung erfolgreich ist. Dies ist eine vernünftige Annahme, jedoch letztendlich falsch (ab .NET 3.5), und es ist trivial, dies für Ihre Version der CLR zu überprüfen. Führen Sie einfach diesen Beispielcode aus.

Auf meinem Computer schlägt der zweite Assembly-Ladevorgang fehl, und die letzten beiden Zeilen des Fusionsprotokolls machen deutlich, warum:

.NET Framework Version: 2.0.50727.3521
---
Attempting to load Assembly: Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f
Successfully loaded Assembly: Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f
---
Attempting to load Assembly: Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
Assembly binding for  failed:
System.IO.FileLoadException: Could not load file or Assembly 'Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, 
PublicKeyToken=0b3305902db7183f' or one of its dependencies. The located Assembly's manifest definition 
does not match the Assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f'

=== Pre-bind state information ===
LOG: User = Phoenix\Dani
LOG: DisplayName = Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
 (Fully-specified)
LOG: Appbase = [...]
LOG: Initial PrivatePath = NULL
Calling Assembly : AssemblyBinding, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
LOG: Attempting download of new URL [...].
WRN: Comparing the Assembly name resulted in the mismatch: Revision Number
ERR: Failed to complete setup of Assembly (hr = 0x80131040). Probing terminated.

Ich denke, die Ursache für diese Verwirrung liegt wahrscheinlich darin, dass Microsoft ursprünglich beabsichtigte, diese strikte Übereinstimmung der vollständigen AssemblyVersion etwas nachsichtiger zu gestalten, indem nur die Teile der Major- und Minor-Version berücksichtigt wurden:

„Beim Laden einer Assembly findet die CLR automatisch die neueste installierte Wartungsversion, die der angeforderten Haupt-/Nebenversion der Assembly entspricht.“ - Jeffrey Richter, [CLR über C # (Zweite Ausgabe)] S. 56

Dies war das Verhalten in Beta 1 der 1.0-CLR. Diese Funktion wurde jedoch vor der Version 1.0 entfernt und konnte in .NET 2.0 nicht erneut aufgerufen werden:

„Hinweis: Ich habe gerade beschrieben, wie Sie sich Versionsnummern vorstellen sollten. Leider behandelt die CLR Versionsnummern nicht so. [In .NET 2.0] behandelt die CLR eine Versionsnummer als undurchsichtigen Wert. Wenn eine Assembly von Version 1.2.3.4 einer anderen Assembly abhängt, versucht die CLR, nur Version 1.2.3.4 zu laden (sofern keine Bindungsumleitung vorhanden ist) ). Microsoft plant jedoch, das Ladeprogramm der CLR in einer zukünftigen Version so zu ändern, dass es den neuesten Build/die neueste Version für eine bestimmte Haupt-/Nebenversion einer Assembly lädt . Wenn der Loader beispielsweise in einer zukünftigen Version der CLR versucht, Version 1.2.3.4 einer Assembly zu finden, und Version 1.2.5.0 vorhanden ist, sucht der Loader automatisch nach der neuesten Wartungsversion. Dies wird eine sehr willkommene Änderung am Lader der CLR sein - ich kann es kaum erwarten. “- Jeffrey Richter, [CLR via C # (Second Edition)] S. 164 (Schwerpunkt Mine)

Da diese Änderung noch nicht implementiert wurde, kann ich davon ausgehen, dass Microsoft diese Absicht zurückverfolgt hat, und es ist möglicherweise zu spät, dies jetzt zu ändern. Ich habe versucht, im Internet zu suchen, um herauszufinden, was mit diesen Plänen geschehen ist, konnte aber keine Antworten finden. Ich wollte immer noch auf den Grund gehen.

Also schrieb ich Jeff Richter eine E-Mail und fragte ihn direkt - ich dachte, wenn jemand wüsste, was passiert ist, würde er es sein.

Er antwortete innerhalb von 12 Stunden, nicht weniger als an einem Samstagmorgen, und stellte klar, dass der .NET 1.0 Beta 1-Loader diesen Mechanismus der automatischen aktualisierenden Wiederherstellung implementiert hat, um den neuesten verfügbaren Build und die neueste Revision einer Assembly abzurufen wurde zurückgesetzt, bevor .NET 1.0 ausgeliefert wurde. Später sollte dies wiederbelebt werden, es gelang jedoch nicht, es vor Auslieferung der CLR 2.0 zu schaffen. Dann kam Silverlight, das für das CLR-Team Priorität hatte, sodass sich diese Funktionalität weiter verzögerte. In der Zwischenzeit sind die meisten Leute, die in den Tagen von CLR 1.0 Beta 1 unterwegs waren, inzwischen umgezogen. Es ist daher unwahrscheinlich, dass dies trotz der bereits geleisteten harten Arbeit zum Tageslicht wird.

Das gegenwärtige Verhalten scheint hier zu bleiben.

Aus meiner Diskussion mit Jeff ist auch hervorzuheben, dass AssemblyFileVersion erst nach dem Entfernen des automatischen Rollforward-Mechanismus hinzugefügt wurde - da nach 1.0 Beta 1 jede Änderung an AssemblyVersion für Ihre Kunden eine bahnbrechende Änderung war Nirgendwo können Sie Ihre Build-Nummer sicher aufbewahren. AssemblyFileVersion ist dieser sichere Hafen, da es von der CLR nie automatisch geprüft wird. Vielleicht ist es auf diese Weise klarer, zwei separate Versionsnummern mit unterschiedlichen Bedeutungen zu haben, als zu versuchen, diese Trennung zwischen den Haupt-/Neben- (Breaking) und den Build-/Revision-Teilen (Non-Breaking) der AssemblyVersion vorzunehmen.

Fazit: Überlegen Sie genau, wann Sie Ihr AssemblyVersion ändern.

Wenn Sie Assemblys versenden, auf die andere Entwickler verweisen, sollten Sie äußerst vorsichtig sein, wenn Sie die AssemblyVersion dieser Assemblys ändern (und nicht ändern). Alle Änderungen an der AssemblyVersion führen dazu, dass Anwendungsentwickler entweder die neue Version erneut kompilieren müssen (um diese AssemblyRef-Einträge zu aktualisieren) oder die Assembly-Bindungsumleitungen verwenden müssen, um die Bindung manuell zu überschreiben.

  • Ändern Sie nicht die AssemblyVersion für eine Wartungsversion, die abwärtskompatibel sein soll.
  • Do Ändern Sie die AssemblyVersion für eine Version, von der Sie wissen, dass sie aktuelle Änderungen enthält.

Schauen Sie sich die Versionsattribute auf mscorlib noch einmal an:

// Assembly mscorlib, Version 2.0.0.0
[Assembly: AssemblyFileVersion("2.0.50727.3521")]
[Assembly: AssemblyInformationalVersion("2.0.50727.3521")]
[Assembly: AssemblyVersion("2.0.0.0")]

Beachten Sie, dass es sich um die AssemblyFileVersion handelt, die alle interessanten Serviceinformationen enthält (im Revisionsteil dieser Version erfahren Sie, auf welchem ​​Service Pack Sie sich befinden), während die AssemblyVersion auf einem langweiligen alten 2.0.0.0-Stand ist. Jede Änderung an der AssemblyVersion würde jede .NET-Anwendung, die auf mscorlib.dll verweist, zwingen, die neue Version erneut zu kompilieren!

576
Daniel Fortunov

AssemblyVersion bleibt so ziemlich intern in .NET, während AssemblyFileVersion das ist, was Windows sieht. Wenn Sie zu den Eigenschaften einer Assembly in einem Verzeichnis wechseln und zur Registerkarte "Version" wechseln, wird oben "AssemblyFileVersion" angezeigt. Wenn Sie Dateien nach Version sortieren, wird dies vom Explorer verwendet.

Das AssemblyInformationalVersion entspricht der "Produktversion" und ist nur für den "menschlichen Gebrauch" gedacht.

AssemblyVersion ist sicherlich das Wichtigste, aber ich würde AssemblyFileVersion auch nicht überspringen. Wenn Sie AssemblyInformationalVersion nicht angeben, fügt der Compiler es für Sie hinzu, indem Sie die "Revision" Ihrer Versionsnummer entfernen und das major.minor.build verlassen.

43
Bob King

AssemblyInformationalVersion und AssemblyFileVersion werden angezeigt, wenn Sie die Versionsinformationen für eine Datei über den Windows-Explorer anzeigen, indem Sie die Dateieigenschaften anzeigen. Diese Attribute werden tatsächlich in eine vom Compiler erstellte Ressource VERSION_INFO Kompiliert.

AssemblyInformationalVersion ist der Wert für "Produktversion". AssemblyFileVersion ist der Wert für "Dateiversion".

AssemblyVersion ist spezifisch für .NET-Assemblys und wird vom .NET-Assembly-Loader verwendet, um zu ermitteln, welche Version einer Assembly zur Laufzeit geladen/gebunden werden soll.

Von diesen ist das einzige Attribut AssemblyVersion, das von .NET unbedingt benötigt wird. Leider kann es auch zu den meisten Problemen kommen, wenn es wahllos geändert wird, insbesondere wenn Sie Ihre Assemblys stark benennen.

22
Scott Dorman

Um diese Frage auf dem neuesten Stand zu halten, sollte hervorgehoben werden, dass AssemblyInformationalVersion von NuGet verwendet wird und das Paketversion einschließlich aller Vorabversionssuffixe widerspiegelt.

Zum Beispiel eine AssemblyVersion von 1.0.3. *, Die mit dem asp.net-Kern dotnet-cli geliefert wird

dotnet pack --version-suffix ci-7 src/MyProject

Produziert ein Paket mit Version 1.0.3-ci-7, das Sie mit Reflection überprüfen können:

CustomAttributeExtensions.GetCustomAttribute<AssemblyInformationalVersionAttribute>(asm);
8
KCD

Es lohnt sich, einige andere Dinge zu beachten:

1) Wie im Windows Explorer-Dialogfeld "Eigenschaften" für die generierte Baugruppendatei angezeigt, gibt es zwei Bereiche mit der Bezeichnung "Dateiversion". Die in der Kopfzeile des Dialogfelds angezeigte zeigt die AssemblyVersion, nicht die AssemblyFileVersion.

Im Abschnitt Andere Versionsinformationen gibt es ein weiteres Element namens "Dateiversion". Hier können Sie sehen, was als AssemblyFileVersion eingegeben wurde.

2) AssemblyFileVersion ist nur einfacher Text. Es muss nicht den Einschränkungen des Nummerierungsschemas von AssemblyVersion entsprechen (<build> <65 KB, z. B.). Es kann 3.2. <Release-Tag-Text>. <Datum/Uhrzeit> sein, wenn Sie möchten. Ihr Build-System muss die Token ausfüllen.

Darüber hinaus unterliegt AssemblyVersion nicht dem Platzhalteraustausch. Wenn Sie in AssemblyInfo.cs nur den Wert "3.0.1. *" Haben, wird genau dies im Element Andere Versionsinformationen-> Dateiversion angezeigt.

3) Ich weiß jedoch nicht, wie sich die Verwendung anderer als numerischer Dateiversionsnummern auf einen Installer auswirkt.

7
DavidM

Wenn die AssemblyVersion einer Assembly geändert wird, Wenn sie einen starken Namen hat, müssen die referenzierenden Assemblys neu kompiliert werden, andernfalls wird die Assembly nicht geladen! Wenn es keinen starken Namen hat und nicht explizit zur Projektdatei hinzugefügt wird, wird es beim Erstellen nicht in das Ausgabeverzeichnis kopiert, sodass Sie möglicherweise abhängige Assemblys übersehen, insbesondere nachdem Sie das Ausgabeverzeichnis bereinigt haben.

2
linquize