Question Quelles sont les différences entre AssemblyVersion, AssemblyFileVersion et AssemblyInformationalVersion?


Il existe trois attributs de version d'assembly. Quelles sont les différences? Est-ce correct si j'utilise AssemblyVersion et ignorer le reste?


MSDN dit:

  • AssemblyVersion:

    Spécifie la version de l'assembly attribué.

  • AssemblyFileVersion:

    Indique à un compilateur d'utiliser un numéro de version spécifique pour la ressource de version de fichier Win32. La version du fichier Win32 n'est pas requise pour être le même que le numéro de version de l'assembly.

  • AssemblyInformationalVersion:

    Définit des informations de version supplémentaires pour un manifeste d'assembly.


Ceci est un suivi de Quelles sont les meilleures pratiques pour utiliser les attributs d'assemblage?


766
2017-09-15 16:47


origine


Réponses:


AssemblyVersion

Où les autres assemblages qui référencent votre assemblage vont regarder. Si ce numéro change, les autres assemblées doivent mettre à jour leurs références à votre assembly! le AssemblyVersion est requis.

J'utilise le format: major.minor. Cela entraînerait:

[assembly: AssemblyVersion("1.0")]

AssemblyFileVersion

Utilisé pour le déploiement Vous pouvez augmenter ce nombre pour chaque déploiement. Il est utilisé par les programmes d'installation. Utilisez-le pour marquer les assemblages qui ont le même AssemblyVersion, mais sont générés à partir de différentes constructions.

Sous Windows, il peut être visualisé dans les propriétés du fichier.

Si possible, laissez-le être généré par MSBuild. La AssemblyFileVersion est facultative. Si ce n'est pas le cas, AssemblyVersion est utilisé.

J'utilise le format: major.minor.revision.build, où j'utilise la révision pour le développement (Alpha, Beta, RC et RTM), les Service Packs et les correctifs. Cela entraînerait:

[assembly: AssemblyFileVersion("1.0.3100.1242")]

AssemblyInformationalVersion

La version du produit de l'assemblage. C'est la version que vous utiliseriez lorsque vous parlez aux clients ou pour l'afficher sur votre site Web. Cette version peut être une chaîne, comme '1.0 Release Candidate'.

L'analyse de code s'en plaindra (CA2243) - rapporté à Microsoft (non fixé dans VS2013).

le AssemblyInformationalVersion est optionnel. S'il n'est pas fourni, AssemblyFileVersion est utilisé.

J'utilise le format: major.minor [révision sous forme de chaîne]. Cela entraînerait:

[assembly: AssemblyInformationalVersion("1.0 RC1")]

822
2017-09-15 17:46



La gestion des versions d'assemblys dans .NET peut être une source de confusion étant donné qu'il existe actuellement au moins trois façons de spécifier une version pour votre assemblage.

Voici les trois principaux attributs d'assemblage liés à la version:

// 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")]

Par convention, les quatre parties de la version sont appelées Version majeure, Version mineure, Construire, et Révision.

le AssemblyFileVersion est destiné à identifier de manière unique une construction de assemblage individuel

En règle générale, vous définissez manuellement les majuscules et les minuscules AssemblyFileVersion pour refléter la version de l'assemblage, puis incrémentez la construction et / ou la révision chaque fois que votre système de compilation compile l'assemblage. Le AssemblyFileVersion devrait vous permettre d'identifier de façon unique une construction de l'assemblage, de sorte que vous pouvez l'utiliser comme point de départ pour le débogage de tout problème.

Dans mon projet actuel, le serveur de construction code le numéro de liste des modifications de notre référentiel de contrôle source dans les parties Build et Revision de AssemblyFileVersion. Cela nous permet de mapper directement d'un assembly à son code source, pour tout assembly généré par le serveur de build (sans avoir à utiliser des labels ou des branches dans le contrôle source, ou à conserver manuellement les enregistrements des versions publiées).

Ce numéro de version est stocké dans la ressource de version Win32 et peut être vu lors de l'affichage des pages de propriétés de l'Explorateur Windows pour l'assembly.

Le CLR ne se soucie ni d'examiner le AssemblyFileVersion.

le AssemblyInformationalVersion est destiné à représenter la version de l'ensemble de votre produit

AssemblyInformationalVersion est conçu pour permettre un versionnement cohérent de l'ensemble du produit, qui peut consister en de nombreux assemblages dont la version est indépendante, peut-être avec des politiques de gestion des versions différentes, et potentiellement développés par des équipes disparates.

"Par exemple, la version 2.0 d'un produit   pourrait contenir plusieurs assemblées; un   de ces assemblées est marqué comme   version 1.0 puisque c'est un nouvel assemblage   qui n'a pas livré dans la version 1.0 de la   même produit. En règle générale, vous définissez le   parties majeures et mineures de cette version   nombre pour représenter la version publique   de votre produit. Ensuite, vous incrémentez   les parties de construction et de révision à chaque fois   vous empaquetez un produit complet avec   toutes ses assemblées. "              - Jeffrey Richter, [CLR via C # (Deuxième édition)] p. 57

Le CLR ne se soucie ni d'examiner la AssemblyInformationalVersion.

le AssemblyVersion est la seule version que le CLR se soucie (mais il se soucie de l'ensemble AssemblyVersion)

AssemblyVersion est utilisé par le CLR pour lier à des assemblys fortement nommés. Il est stocké dans la table de métadonnées manifeste AssemblyDef de l'assembly construit et dans la table AssemblyRef de tout assembly qui le référence.

Ceci est très important, car cela signifie que lorsque vous référencez un assembly fortement nommé, vous êtes étroitement lié à une AssemblyVersion spécifique de cet assembly. L'ensemble AssemblyVersion doit correspondre exactement à la liaison pour réussir. Par exemple, si vous référencez la version 1.0.0.0 d'un assembly fortement nommé au moment de la construction, mais que seule la version 1.0.0.1 de cet assembly est disponible au moment de l'exécution, la liaison échouera! (Vous devrez alors contourner cela en utilisant Redirection de liaison d'assemblage.)

Confusion sur si l'ensemble AssemblyVersion doit correspondre. (Oui.)

Il y a un peu de confusion autour de savoir si l'ensemble AssemblyVersion doit être une correspondance exacte pour qu'un assembly soit chargé. Certaines personnes sont sous la fausse croyance que seules les parties majeures et mineures de l'AssemblyVersion doivent correspondre pour que la liaison réussisse. C'est une supposition sensée, mais elle est finalement incorrecte (à partir de .NET 3.5), et il est trivial de vérifier cela pour votre version du CLR. Juste exécuter cet exemple de code.

Sur ma machine, la deuxième charge d'assemblage échoue, et les deux dernières lignes du journal de fusion rendent parfaitement clair pourquoi:

.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.

Je pense que la source de cette confusion est probablement due au fait que Microsoft avait l'intention d'être un peu plus indulgent sur cette correspondance stricte de l'AssemblyVersion complète, en ne faisant correspondre que les parties de versions Major et Minor:

"Lors du chargement d'un assemblage, le CLR trouvera automatiquement la dernière   version de maintenance installée   correspond à la version majeure / mineure du   l'assemblage est demandé. "               - Jeffrey Richter, [CLR via C # (Deuxième édition)] p. 56

C'était le comportement dans Beta 1 du 1.0 CLR, cependant cette fonctionnalité a été supprimée avant la version 1.0, et n'a pas réussi à refaire surface dans .NET 2.0:

"Note: Je viens de décrire comment vous   devrait penser aux numéros de version.   Malheureusement, le CLR ne traite pas   numéros de version de cette façon. [En .NET   2.0], le CLR traite un numéro de version comme une valeur opaque, et si un assemblage   dépend de la version 1.2.3.4 d'un autre   l'assemblage, le CLR essaie de charger   version 1.2.3.4 seulement (à moins qu'une   la redirection est en place). cependant,    Microsoft a l'intention de changer la   Le chargeur de CLR dans une future version   qu'il charge le dernier   construction / révision pour une majeure / mineure donnée   version d'un assemblage. Par exemple,   sur une future version du CLR, si le   loader essaie de trouver la version   1.2.3.4 d'un ensemble et la version 1.2.5.0 existe, le chargeur avec automatiquement ramasser les dernières   version de service. Ce sera très   bienvenue changement au chargeur du CLR - I   car on ne peut pas attendre. "               - Jeffrey Richter, [CLR via C # (Deuxième édition)] p. 164 (Souligné   mien)

Comme ce changement n'a toujours pas été mis en œuvre, je pense qu'il est raisonnable de supposer que Microsoft a fait marche arrière sur cette intention, et il est peut-être trop tard pour changer cela maintenant. J'ai essayé de faire des recherches sur le Web pour savoir ce qui s'est passé avec ces plans, mais je n'ai trouvé aucune réponse. Je voulais toujours aller au fond des choses.

J'ai donc envoyé un courriel à Jeff Richter et je lui ai demandé directement - je me suis dit que si quelqu'un savait ce qui s'était passé, ce serait lui.

Il a répondu dans les 12 heures, un samedi matin pas moins, et a précisé que le chargeur .NET 1.0 Beta 1 a mis en œuvre ce mécanisme de «roll-forward automatique» pour récupérer les dernières versions Build et Revision d'un assemblage, mais ce comportement retourné avant .NET 1.0 livré. Il a été plus tard destiné à relancer cela, mais il ne l'a pas fait avant le CLR 2.0 livré. Puis Silverlight, qui a pris la priorité pour l'équipe CLR, cette fonctionnalité a été retardée davantage. Entre-temps, la plupart des gens qui se trouvaient à l'époque du CLR 1.0 Beta 1 ont évolué depuis, il est donc peu probable que cela se fasse jour, malgré tout le dur labeur qui y a déjà été consacré.

Le comportement actuel, semble-t-il, est là pour rester.

Il vaut également la peine de noter de ma discussion avec Jeff que AssemblyFileVersion n'a été ajouté qu'après la suppression du mécanisme de "roll-forward automatique" - parce qu'après 1.0 Beta 1, toute modification apportée à AssemblyVersion était un changement important pour vos clients. nulle part pour stocker en toute sécurité votre numéro de build. AssemblyFileVersion est ce refuge, car il n'est jamais examiné automatiquement par le CLR. Peut-être que c'est plus clair de cette façon, ayant deux numéros de version séparés, avec des significations séparées, plutôt que d'essayer de faire cette séparation entre les parties Major / Minor (rupture) et Build / Revision (non-breaking) de AssemblyVersion.

La ligne du bas: Réfléchissez bien à quand vous changez votre AssemblyVersion

La morale est que si vous expédiez des assemblages que d'autres développeurs vont référencer, vous devez faire très attention quand vous changez (et ne changez pas) la AssemblyVersion de ces assemblages. Toute modification apportée à AssemblyVersion signifie que les développeurs d'applications devront soit recompiler la nouvelle version (pour mettre à jour ces entrées AssemblyRef), soit utiliser les redirections de liaison d'assembly pour remplacer manuellement la liaison.

  • Ne pas Modifiez AssemblyVersion pour une version de maintenance qui est destinée à être rétrocompatible.
  • Faire Modifiez le AssemblyVersion pour une version dont vous savez qu'il a des modifications de rupture.

Jetez juste un coup d'oeil aux attributs de version sur mscorlib:

// 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")]

Notez que c'est AssemblyFileVersion qui contient toutes les informations de maintenance intéressantes (c'est la partie Revision de cette version qui vous indique quel Service Pack vous êtes), pendant ce temps, AssemblyVersion est fixé à un ancien 2.0.0.0 ennuyeux. Toute modification apportée à AssemblyVersion forcerait chaque application .NET référençant mscorlib.dll à recompiler la nouvelle version!


541
2018-04-29 12:01



AssemblyVersion reste assez interne à .NET, tandis que AssemblyFileVersion est ce que Windows voit. Si vous allez dans les propriétés d'un assembly assis dans un répertoire et passez à l'onglet version, le AssemblyFileVersion est ce que vous verrez en haut. Si vous triez les fichiers par version, c'est ce qui est utilisé par l'explorateur.

le AssemblyInformationalVersion correspond à la "version du produit" et est destiné à être purement "utilisé par l'homme".

AssemblyVersion est certainement le plus important, mais je ne sauterais pas AssemblyFileVersion, non plus. Si vous ne fournissez pas AssemblyInformationalVersion, le compilateur l'ajoute pour vous en enlevant le morceau "revision" de votre numéro de version et en laissant le major.minor.build.


39
2017-09-15 16:51



AssemblyInformationalVersion et AssemblyFileVersion sont affichés lorsque vous affichez les informations "Version" sur un fichier via l'Explorateur Windows en affichant les propriétés du fichier. Ces attributs sont réellement compilés dans un VERSION_INFO ressource créée par le compilateur.

AssemblyInformationalVersion est la valeur "Version du produit". AssemblyFileVersion est la valeur "Version du fichier".

le AssemblyVersion est spécifique aux assemblys .NET et est utilisé par le chargeur d'assembly .NET pour connaître la version d'un assembly à charger / lier lors de l'exécution.

Parmi ceux-ci, le seul qui est absolument requis par .NET est le AssemblyVersion attribut. Malheureusement, il peut également causer le plus de problèmes quand il change sans discernement, surtout si vous êtes fort en nommant vos assemblys.


21
2017-09-15 16:52



Il vaut la peine de noter d'autres choses:

1) Comme indiqué dans la boîte de dialogue Propriétés de Windows Explorer pour le fichier d'assemblage généré, il existe deux emplacements appelés "Version du fichier". Celui vu dans l'en-tête de la boîte de dialogue montre le AssemblyVersion, pas le AssemblyFileVersion.

Dans la section Informations sur la version, il existe un autre élément appelé "Version du fichier". C'est ici que vous pouvez voir ce qui a été saisi en tant que AssemblyFileVersion.

2) AssemblyFileVersion est juste du texte brut. Il n'a pas à se conformer aux restrictions du schéma de numérotation que AssemblyVersion effectue (<build> <65K, par exemple). Il peut être 3.2. <Release tag text>. <Datetime>, si vous le souhaitez. Votre système de construction devra remplir les jetons.

En outre, il n'est pas soumis au remplacement générique que AssemblyVersion est. Si vous avez juste une valeur de "3.0.1. *" Dans AssemblyInfo.cs, c'est exactement ce qui apparaîtra dans l'élément Other version information-> File Version.

3) Je ne connais pas l'impact sur un installateur d'utiliser autre chose que des numéros de version de fichiers numériques, cependant.


7
2017-11-27 22:51



Pour garder cette question à jour, il vaut la peine de souligner que AssemblyInformationalVersion est utilisé par NuGet et reflète la version du paquet y compris tout suffixe pré-version.

Par exemple une AssemblyVersion de 1.0.3. * Empaquetée avec le noyau asp.net dotnet-cli

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

Produit un paquet avec la version 1.0.3-ci-7 que vous pouvez inspecter avec réflexion en utilisant:

CustomAttributeExtensions.GetCustomAttribute<AssemblyInformationalVersionAttribute>(asm);

6
2018-06-23 04:51



Lorsque la AssemblyVersion d'un assembly est modifiée, S'il a un nom fort, les assemblages de référencement doivent être recompilés, sinon l'assemblage ne se charge pas! Si elle n'a pas de nom fort, si elle n'est pas explicitement ajoutée au fichier de projet, elle ne sera pas copiée dans le répertoire de sortie lors de la construction, vous risquez de manquer des assemblages dépendants, surtout après avoir nettoyé le répertoire de sortie.


2
2018-02-17 05:21