it-swarm-es.tech

¿Cuáles son las diferencias entre AssemblyVersion, AssemblyFileVersion y AssemblyInformationalVersion?

Hay tres atributos de la versión de ensamblaje. ¿Qué son las diferencias? ¿Está bien si uso AssemblyVersion e ignoro el resto?


MSDN dice:

  • AssemblyVersion :

    Especifica la versión del ensamblaje que se atribuye.

  • AssemblyFileVersion :

    Indica a un compilador que use un número de versión específico para el recurso de versión de archivo Win32. No se requiere que la versión del archivo Win32 sea la misma que el número de versión de la Asamblea.

  • AssemblyInformationalVersion :

    Define información de versión adicional para un manifiesto de ensamblado.


Este es un seguimiento de ¿Cuáles son las mejores prácticas para usar los atributos de ensamblaje?

820
Jakub Šturc

AssemblyVersion

Donde se verán otras asambleas que hagan referencia a su Asamblea. ¡Si este número cambia, otros conjuntos tienen que actualizar sus referencias a su conjunto! La AssemblyVersion es obligatoria.

Yo uso el formato: major.minor. Esto resultaría en:

[Assembly: AssemblyVersion("1.0")]

AssemblyFileVersion

Utilizado para la implementación. Puede aumentar este número para cada implementación. Es utilizado por los programas de configuración. Úselo para marcar ensamblajes que tienen la misma AssemblyVersion, pero que se generan a partir de diferentes construcciones.

En Windows, se puede ver en las propiedades del archivo.

Si es posible, deje que sea generado por MSBuild. El AssemblyFileVersion es opcional. Si no se da, se usa la AssemblyVersion.

Utilizo el formato: major.minor.revision.build, donde uso la revisión para la etapa de desarrollo (Alpha, Beta, RC y RTM), paquetes de servicio y correcciones. Esto resultaría en:

[Assembly: AssemblyFileVersion("1.0.3100.1242")]

AssemblyInformationalVersion

La versión del producto de la Asamblea. Esta es la versión que usaría al hablar con los clientes o para mostrarla en su sitio web. Esta versión puede ser una cadena, como '1.0 Release Candidate'.

El Análisis de Código se quejará al respecto (CA2243) - reportado a Microsoft (no corregido en VS2013).

La AssemblyInformationalVersion es opcional. Si no se da, se usa AssemblyFileVersion.

Uso el formato: major.minor [revisión como cadena]. Esto resultaría en:

[Assembly: AssemblyInformationalVersion("1.0 RC1")]
866
Rémy van Duijkeren

La versión de ensamblajes en .NET puede ser una perspectiva confusa dado que actualmente hay al menos tres formas de especificar una versión para su ensamblaje.

Aquí están los tres principales atributos de ensamblaje relacionados con la versión:

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

Por convención, las cuatro partes de la versión se denominan Versión principal , Versión menor , Generar , y Revisión .

La AssemblyFileVersion está destinada a identificar de forma única una compilación de ensamblaje individual

Normalmente, configurará manualmente el Major y Minor AssemblyFileVersion para reflejar la versión del ensamblado, luego incrementará la compilación y/o la revisión cada vez que su sistema de compilación compile el ensamblaje. AssemblyFileVersion debe permitirle identificar de forma única una compilación de la Asamblea, de modo que pueda usarla como punto de partida para depurar cualquier problema.

En mi proyecto actual, el servidor de compilación codifica el número de lista de cambios de nuestro repositorio de control de origen en las partes de compilación y revisión de AssemblyFileVersion. Esto nos permite asignar directamente desde un ensamblaje a su código fuente, para cualquier ensamblaje generado por el servidor de compilación (sin tener que usar etiquetas o sucursales en el control de origen, o mantener manualmente los registros de las versiones publicadas).

Este número de versión se almacena en el recurso de versión de Win32 y se puede ver al ver las páginas de propiedades del Explorador de Windows para el ensamblaje.

El CLR no se preocupa ni examina la AssemblyFileVersion.

La AssemblyInformationalVersion pretende representar la versión de todo su producto

La AssemblyInformationalVersion está pensada para permitir un versionado coherente de todo el producto, que puede consistir en muchos ensamblajes que se versionan de forma independiente, tal vez con diferentes políticas de versionamiento, y potencialmente desarrollados por equipos dispares.

“Por ejemplo, la versión 2.0 de un producto puede contener varios ensamblajes; uno de estos ensamblajes está marcado como versión 1.0 ya que es un nuevo ensamblaje que no se envió en la versión 1.0 del mismo producto. Por lo general, establece que las partes principales y secundarias de este número de versión representan la versión pública de su producto. Luego, incrementa las partes de compilación y revisión cada vez que empaqueta un producto completo con todos sus ensamblajes ”. - Jeffrey Richter, [CLR a través de C # (Segunda edición)] p. 57

El CLR no se preocupa ni examina la AssemblyInformationalVersion.

La AssemblyVersion es la única versión que le importa a CLR (pero le importa toda la AssemblyVersion)

El CLR utiliza la AssemblyVersion para enlazar a ensamblados con nombre seguro. Se almacena en la tabla de metadatos de manifiesto AssemblyDef del ensamblado construido y en la tabla AssemblyRef de cualquier ensamblado que lo haga referencia.

Esto es muy importante, porque significa que cuando hace referencia a una Asamblea con un nombre fuerte, está estrechamente vinculado a una Asamblea específica de esa Asamblea. Toda la AssemblyVersion debe ser una coincidencia exacta para que el enlace tenga éxito. Por ejemplo, si hace referencia a la versión 1.0.0.0 de un ensamblado con un nombre seguro en el momento de la compilación, pero solo la versión 1.0.0.1 de ese ensamblaje está disponible en tiempo de ejecución, ¡el enlace fallará! (Luego tendrá que solucionar este problema utilizando Redirección de enlace de ensamblaje .)

Confusión sobre si toda la AssemblyVersion tiene que coincidir. (Sí, lo hace).

Existe una pequeña confusión acerca de si la AssemblyVersion completa tiene que ser una coincidencia exacta para que se cargue un Assembly. Algunas personas tienen la falsa creencia de que solo las partes Mayor y Menor de la Versión de la Asamblea deben coincidir para que la vinculación tenga éxito. Este es un supuesto razonable, sin embargo, en última instancia, es incorrecto (a partir de .NET 3.5), y es trivial verificarlo para su versión de CLR. Simplemente ejecute este código de ejemplo .

En mi máquina, la segunda carga de ensamblaje falla, y las dos últimas líneas del registro de fusión dejan perfectamente en claro por qué:

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

Creo que la fuente de esta confusión es probablemente porque Microsoft originalmente pretendía ser un poco más indulgente en esta coincidencia estricta de la versión completa de la AssemblyVersion, al hacer coincidir solo las partes de las versiones Major y Minor:

"Al cargar un ensamblaje, el CLR encontrará automáticamente la última versión de servicio instalada que coincide con la versión mayor/menor del ensamblaje que se solicita". - Jeffrey Richter, [CLR a través de C # (Segunda edición)] pág. 56

Este fue el comportamiento en la versión Beta 1 de la CLR 1.0, sin embargo, esta característica se eliminó antes de la versión 1.0 y no se ha logrado volver a aparecer en .NET 2.0:

“Nota: acabo de describir cómo debes pensar en los números de versión. Desafortunadamente, el CLR no trata los números de versión de esta manera. [En .NET 2.0], el CLR trata un número de versión como un valor opaco, y si un ensamblado depende de la versión 1.2.3.4 de otro ensamblaje, el CLR intenta cargar la versión 1.2.3.4 solamente (a menos que haya una redirección de enlace en su lugar) ). Sin embargo, Microsoft tiene planes de cambiar el cargador de CLR en una versión futura para que cargue la última versión/compilación de una versión mayor/menor de un ensamblado . Por ejemplo, en una versión futura del CLR, si el cargador está tratando de encontrar la versión 1.2.3.4 de un Ensamblaje y existe la versión 1.2.5.0, el cargador recogerá automáticamente la última versión de servicio. Este será un cambio muy bienvenido para el cargador de CLR, por lo que no puedo esperar ". - Jeffrey Richter, [CLR a través de C # (Segunda edición)] p. 164 (énfasis mío)

Como este cambio aún no se ha implementado, creo que es seguro suponer que Microsoft había hecho un seguimiento de esta intención, y tal vez sea demasiado tarde para cambiar esto ahora. Intenté buscar en la web para averiguar qué sucedió con estos planes, pero no pude encontrar ninguna respuesta. Todavía quería llegar al fondo de esto.

Así que le envié un correo electrónico a Jeff Richter y le pregunté directamente: pensé que si alguien sabía lo que sucedió, sería él.

Respondió en menos de 12 horas, un sábado por la mañana, y aclaró que el cargador .NET 1.0 Beta 1 implementó este mecanismo de "avance automático" para recoger la última versión y compilación disponibles de un ensamblaje, pero este comportamiento fue revertido antes de .NET 1.0 enviado. Más tarde se intentó revivir esto, pero no se logró antes de que se lanzara el CLR 2.0. Luego vino Silverlight, que tuvo prioridad para el equipo CLR, por lo que esta funcionalidad se retrasó aún más. Mientras tanto, la mayoría de las personas que se encontraban en los días de CLR 1.0 Beta 1 se han movido, por lo que es poco probable que esto se vea la luz del día, a pesar de todo el arduo trabajo que ya se ha realizado.

El comportamiento actual, al parecer, está aquí para quedarse.

También vale la pena señalar en mi discusión con Jeff que AssemblyFileVersion solo se agregó después de la eliminación del mecanismo de "avance automático", ya que después de la versión 1.0 Beta 1, cualquier cambio en la AssemblyVersion fue un cambio importante para sus clientes. ningún lugar para almacenar de forma segura su número de compilación. AssemblyFileVersion es ese refugio seguro, ya que nunca es examinado automáticamente por el CLR. Tal vez sea más claro de esta manera, tener dos números de versión separados, con significados separados, en lugar de tratar de hacer esa separación entre las partes Mayor/Menor (rompiendo) y Construir/Revisión (no rompiendo) de la AssemblyVersion.

El resultado final: piense con cuidado cuando cambie su AssemblyVersion

La moraleja es que si va a enviar ensamblajes a los que otros desarrolladores van a hacer referencia, debe ser extremadamente cuidadoso cuando cambie (y no) la Asamblea de la versión de esos ensamblajes. Cualquier cambio en AssemblyVersion significará que los desarrolladores de aplicaciones tendrán que volver a compilar contra la nueva versión (para actualizar esas entradas de AssemblyRef) o usar redireccionamientos de enlaces de ensamblados para anular manualmente el enlace.

  • No cambie la AssemblyVersion para una versión de servicio que está diseñada para ser compatible con versiones anteriores.
  • Haz cambia la AssemblyVersion para una versión que sabes que tiene cambios de última hora.

Simplemente eche un vistazo a los atributos de la versión en 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")]

Tenga en cuenta que es AssemblyFileVersion la que contiene toda la información de servicio interesante (es la parte de Revisión de esta versión la que le indica en qué Service Pack está), mientras que AssemblyVersion está arreglado en un antiguo 2.0.0.0 aburrido. ¡Cualquier cambio en la AssemblyVersion obligaría a cada aplicación .NET que hace referencia a mscorlib.dll a volver a compilar contra la nueva versión!

566
Daniel Fortunov

AssemblyVersion prácticamente permanece interna en .NET, mientras que AssemblyFileVersion es lo que Windows ve. Si va a las propiedades de un ensamblado sentado en un directorio y cambia a la pestaña de versión, la AssemblyFileVersion es lo que verá arriba. Si ordena los archivos por versión, esto es lo que usa Explorer.

La AssemblyInformationalVersion se asigna a la "Versión del producto" y está destinada a ser puramente "utilizada por el hombre".

AssemblyVersion es ciertamente lo más importante, pero tampoco me saltearía AssemblyFileVersion. Si no proporciona AssemblyInformationalVersion, el compilador lo agrega por usted eliminando la parte de "revisión" de su número de versión y dejando el major.minor.build.

41
Bob King

AssemblyInformationalVersion y AssemblyFileVersion se muestran cuando ve la información de "Versión" en un archivo a través del Explorador de Windows al ver las propiedades del archivo. Estos atributos realmente se compilan en un recurso VERSION_INFO que es creado por el compilador.

AssemblyInformationalVersion es el valor de "Versión del producto". AssemblyFileVersion es el valor de "Versión del archivo".

La AssemblyVersion es específica de los ensamblados .NET y es utilizada por el cargador de ensamblajes .NET para saber qué versión de un ensamblaje se debe cargar/enlazar en tiempo de ejecución.

De estos, el único que es absolutamente requerido por .NET es el atributo AssemblyVersion. Desafortunadamente, también puede causar la mayoría de los problemas cuando cambia de manera indiscriminada, especialmente si tiene un nombre fuerte para sus ensamblajes.

21
Scott Dorman

Para mantener esta pregunta actualizada, vale la pena resaltar que NuVet utiliza AssemblyInformationalVersion y refleja el versión del paquete incluyendo cualquier sufijo previo al lanzamiento.

Por ejemplo, una AssemblyVersion de 1.0.3. * Empaquetada con asp.net core dotnet-cli

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

Produce un paquete con la versión 1.0.3-ci-7 que puede inspeccionar con reflexión utilizando:

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

Vale la pena señalar algunas otras cosas:

1) Como se muestra en el cuadro de diálogo Propiedades del Explorador de Windows para el archivo de ensamblaje generado, hay dos lugares llamados "Versión del archivo". El que se ve en el encabezado del diálogo muestra la AssemblyVersion, no la AssemblyFileVersion.

En la sección Información de otra versión, hay otro elemento llamado "Versión del archivo". Aquí es donde puede ver lo que se ingresó como AssemblyFileVersion.

2) AssemblyFileVersion es solo texto plano. No tiene que cumplir con las restricciones del esquema de numeración que hace AssemblyVersion (<build> <65K, por ejemplo). Puede ser 3.2. <Release tag text>. <datetime>, si lo desea. Tu sistema de construcción tendrá que completar los tokens.

Además, no está sujeto a la sustitución de comodines que se encuentra en AssemblyVersion. Si solo tiene un valor de "3.0.1. *" En AssemblyInfo.cs, eso es exactamente lo que se mostrará en el elemento Otra versión de información-> Versión de archivo.

3) Sin embargo, no sé el impacto sobre un instalador de usar algo distinto a los números de versión de archivo numérico.

7
DavidM

Cuando se modifica la Asamblea de una Asamblea, si tiene un nombre seguro, es necesario volver a compilar las unidades de referencia, de lo contrario, ¡la Asamblea no se carga! Si no tiene un nombre seguro, si no se agrega explícitamente al archivo de proyecto, no se copiará en el directorio de salida cuando se genere, por lo que puede perder ensamblajes dependientes, especialmente después de limpiar el directorio de salida.

2
linquize