Quais são as diferenças entre AssemblyVersion, AssemblyFileVersion e AssemblyInformationalVersion?

StackOverflow https://stackoverflow.com/questions/64602

  •  09-06-2019
  •  | 
  •  

Pergunta

Existem três atributos de versão do assembly.Quais são as diferenças?Tudo bem se eu usar AssemblyVersion e ignorar o resto?


MSDN diz:

  • Versão Assembly:

    Especifica a versão do assembly que está sendo atribuída.

  • AssemblyFileVersão:

    Instrui um compilador a usar um número de versão específico para o recurso de versão do arquivo Win32.A versão do arquivo Win32 não precisa ser igual ao número da versão do assembly.

  • AssemblyInformationalVersion:

    Define informações adicionais de versão para um manifesto de assembly.


Este é um acompanhamento Quais são as melhores práticas para usar atributos de montagem?

Foi útil?

Solução

Versão Assembly

Onde serão exibidas outras montagens que fazem referência à sua montagem.Se esse número mudar, outras montagens terão que atualizar suas referências à sua montagem!O AssemblyVersion é necessário.

Eu uso o formato: maior.menor.Isso resultaria em:

[assembly: AssemblyVersion("1.0")]

AssemblyFileVersão

Usado para implantação.Você pode aumentar esse número para cada implantação.É usado por programas de configuração.Use-o para marcar montagens que possuem o mesmo AssemblyVersion, mas são gerados a partir de compilações diferentes.

No Windows, ele pode ser visualizado nas propriedades do arquivo.

Se possível, deixe-o ser gerado pelo MSBuild.O AssemblyFileVersion é opcional.Se não for fornecido, o AssemblyVersion será usado.

Eu uso o formato: major.minor.revision.build, onde utilizo revisão para fase de desenvolvimento (Alpha, Beta, RC e RTM), service packs e hot fixes.Isso resultaria em:

[assembly: AssemblyFileVersion("1.0.3100.1242")]

AssemblyInformationalVersion

A versão do produto do assembly.Esta é a versão que você usaria ao conversar com clientes ou para exibir em seu site.Esta versão pode ser uma string, como '1.0 Candidato a Lançamento'.

A Análise de Código irá reclamar disso (CA2243) - relatado à Microsoft (não corrigido no VS2013).

O AssemblyInformationalVersion é opcional.Se não for fornecido, o AssemblyFileVersion será usado.

Eu uso o formato: major.minor [revisão como string].Isso resultaria em:

[assembly: AssemblyInformationalVersion("1.0 RC1")]

Outras dicas

O controle de versão de assemblies no .NET pode ser uma perspectiva confusa, visto que atualmente existem pelo menos três maneiras de especificar uma versão para seu assembly.

Aqui estão os três principais atributos de montagem relacionados à versão:

// 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 convenção, as quatro partes da versão são referidas como Versão principal, Versão secundária, Construir, e Revisão.

O AssemblyFileVersion destina-se a identificar exclusivamente uma construção do montagem individual

Normalmente, você definirá manualmente AssemblyFileVersion principal e secundário para refletir a versão do assembly e, em seguida, incrementará a compilação e/ou revisão sempre que seu sistema de compilação compilar o assembly.O AssemblyFileVersion deve permitir identificar exclusivamente uma compilação do assembly, para que você possa usá-lo como ponto de partida para depurar quaisquer problemas.

No meu projeto atual, temos o servidor de compilação codificando o número da lista de alterações do nosso repositório de controle de origem nas partes Build e Revision do AssemblyFileVersion.Isso nos permite mapear diretamente de um assembly para seu código-fonte, para qualquer assembly gerado pelo servidor de compilação (sem ter que usar rótulos ou ramificações no controle de origem, ou manter manualmente quaisquer registros de versões lançadas).

Esse número de versão é armazenado no recurso de versão Win32 e pode ser visto ao visualizar as páginas de propriedades do Windows Explorer para o assembly.

O CLR não se preocupa nem examina o AssemblyFileVersion.

O AssemblyInformationalVersion destina-se a representar a versão de todo o seu produto

O AssemblyInformationalVersion destina-se a permitir o controle de versão coerente de todo o produto, que pode consistir em muitos assemblies com controle de versão independente, talvez com políticas de controle de versão diferentes, e potencialmente desenvolvidos por equipes diferentes.

“Por exemplo, a versão 2.0 de um produto pode conter vários assemblies;Um desses assemblies é marcado como versão 1.0, pois é uma nova montagem que não foi enviada na versão 1.0 do mesmo produto.Normalmente, você define as partes principais e menores deste número de versão para representar a versão pública do seu produto.Em seguida, você incrementa as peças de construção e revisão cada vez que empacotará um produto completo com todos os seus conjuntos. ” - Jeffrey Richter, [CLR via C# (segunda edição)] p.57

O CLR não se preocupa nem examina o AssemblyInformationalVersion.

O AssemblyVersion é a única versão com a qual o CLR se preocupa (mas se preocupa com todo o AssemblyVersion)

O AssemblyVersion é usado pelo CLR para vincular a assemblies com nomes fortes.Ele é armazenado na tabela de metadados do manifesto AssemblyDef do assembly criado e na tabela AssemblyRef de qualquer assembly que o faça referência.

Isso é muito importante porque significa que, ao fazer referência a um assembly com nome forte, você estará fortemente vinculado a uma AssemblyVersion específica desse assembly.Todo o AssemblyVersion deve ser uma correspondência exata para que a associação seja bem-sucedida.Por exemplo, se você fizer referência à versão 1.0.0.0 de um assembly com nome forte em tempo de compilação, mas apenas a versão 1.0.0.1 desse assembly estiver disponível em tempo de execução, a ligação falhará!(Você terá então que contornar isso usando Redirecionamento de associação de assembly.)

Confusão sobre se todo o AssemblyVersion tem que combinar.(Sim.)

Há um pouco de confusão sobre se todo o AssemblyVersion precisa ser uma correspondência exata para que um assembly seja carregado.Algumas pessoas têm a falsa crença de que apenas as partes Maiores e Menores da AssemblyVersion precisam corresponder para que a ligação seja bem-sucedida.Esta é uma suposição sensata, mas é incorreta (a partir do .NET 3.5) e é trivial verificar isso para sua versão do CLR.Basta executar este código de exemplo.

Na minha máquina, a segunda carga de montagem falha e as duas últimas linhas do log de fusão deixam perfeitamente claro o porquê:

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

Acho que a fonte dessa confusão é provavelmente porque a Microsoft originalmente pretendia ser um pouco mais tolerante com essa correspondência estrita da AssemblyVersion completa, combinando apenas as partes da versão principal e secundária:

“Ao carregar uma montagem, o CLR encontrará automaticamente a versão mais recente de manutenção instalada que corresponde à versão principal/menor da Assembléia que está sendo solicitada.” - Jeffrey Richter, [CLR via C# (segunda edição)] p.56

Esse era o comportamento no Beta 1 do CLR 1.0, porém esse recurso foi removido antes do lançamento 1.0 e não conseguiu reaparecer no .NET 2.0:

"Observação:Acabei de descrever como você deve pensar nos números de versão.Infelizmente, o CLR não trata os números da versão dessa maneira.In .NET 2.0], o CLR trata um número de versão como um valor opaco e, se uma montagem depende da versão 1.2.3.4 de outra montagem, o CLR tenta carregar apenas a versão 1.2.3.4 (a menos que um redirecionamento de ligação esteja no local ).No entanto, A Microsoft planeja alterar o carregador do CLR em uma versão futura, para que carregue a última compilação/revisão para uma determinada versão maior/menor de uma montagem.Por exemplo, em uma versão futura do CLR, se o carregador estiver tentando encontrar a versão 1.2.3.4 de uma montagem e a versão 1.2.5.0 existe, o carregador com a versão mais recente da versão mais recente.Esta será uma mudança muito bem -vinda para o carregador do CLR - eu posso esperar. ” - Jeffrey Richter, [CLR via C# (segunda edição)] p.164 (ênfase minha)

Como esta mudança ainda não foi implementada, penso que é seguro assumir que a Microsoft voltou atrás nesta intenção, e talvez seja tarde demais para mudar isto agora.Tentei pesquisar na web para descobrir o que aconteceu com esses planos, mas não consegui encontrar nenhuma resposta.Eu ainda queria chegar ao fundo da questão.

Então enviei um e-mail para Jeff Richter e perguntei diretamente a ele - imaginei que se alguém soubesse o que aconteceu, seria ele.

Ele respondeu dentro de 12 horas, nada menos que uma manhã de sábado, e esclareceu que o carregador .NET 1.0 Beta 1 implementou esse mecanismo de 'avanço automático' para obter a versão mais recente disponível de compilação e revisão de um assembly, mas esse comportamento foi revertido antes do lançamento do .NET 1.0.Posteriormente, pretendia-se reviver isso, mas não foi implementado antes do lançamento do CLR 2.0.Depois veio o Silverlight, que teve prioridade para a equipe CLR, então essa funcionalidade foi adiada ainda mais.Enquanto isso, a maioria das pessoas que existiam na época do CLR 1.0 Beta 1 seguiram em frente, então é improvável que isso veja a luz do dia, apesar de todo o trabalho duro que já foi feito.

O comportamento atual, ao que parece, veio para ficar.

Também vale a pena notar em minha discussão com Jeff que AssemblyFileVersion só foi adicionado após a remoção do mecanismo de 'roll-forward automático' - porque após 1.0 Beta 1, qualquer alteração no AssemblyVersion era uma alteração significativa para seus clientes, havia então nenhum lugar para armazenar com segurança seu número de compilação.AssemblyFileVersion é esse porto seguro, já que nunca é examinado automaticamente pelo CLR.Talvez seja mais claro assim, ter dois números de versão separados, com significados separados, em vez de tentar fazer essa separação entre as partes Maior/Secundária (quebra) e as partes de Construção/Revisão (não-quebra) da AssemblyVersion.

O resultado final:Pense cuidadosamente sobre quando você muda seu AssemblyVersion

A moral é que se você estiver enviando assemblies aos quais outros desenvolvedores farão referência, você precisa ser extremamente cuidadoso ao alterar (ou não) o AssemblyVersion desses assemblies.Quaisquer alterações no AssemblyVersion significarão que os desenvolvedores de aplicativos terão que recompilar com a nova versão (para atualizar essas entradas AssemblyRef) ou usar redirecionamentos de ligação de assembly para substituir manualmente a ligação.

  • Não altere o AssemblyVersion para uma versão de serviço que se destina a ser compatível com versões anteriores.
  • Fazer altere o AssemblyVersion para uma versão que você sabe que tem alterações significativas.

Basta dar uma olhada nos atributos de versão no 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")]

Observe que é o AssemblyFileVersion que contém todas as informações de serviço interessantes (é a parte de revisão desta versão que informa em qual Service Pack você está), enquanto o AssemblyVersion é corrigido em um velho e chato 2.0.0.0.Qualquer alteração no AssemblyVersion forçaria todos os aplicativos .NET que fazem referência a mscorlib.dll a recompilar com a nova versão!

AssemblyVersion praticamente permanece interno ao .NET, enquanto AssemblyFileVersion é o que o Windows vê.Se você for para as propriedades de um assembly localizado em um diretório e alternar para a guia de versão, o AssemblyFileVersion é o que você verá no topo.Se você classificar os arquivos por versão, é isso que o Explorer usa.

O AssemblyInformationalVersion mapeia para a "versão do produto" e deve ser puramente "usado por humanos".

AssemblyVersion é certamente o mais importante, mas eu não pularia AssemblyFileVersion, qualquer.Se você não fornecer AssemblyInformationalVersion, o compilador o adiciona para você removendo a parte de "revisão" do número da sua versão e deixando major.minor.build.

AssemblyInformationalVersion e AssemblyFileVersion são exibidos quando você visualiza as informações de "Versão" em um arquivo por meio do Windows Explorer, visualizando as propriedades do arquivo.Na verdade, esses atributos são compilados em um VERSION_INFO recurso criado pelo compilador.

AssemblyInformationalVersion é o valor "Versão do produto". AssemblyFileVersion é o valor "Versão do arquivo".

O AssemblyVersion é específico para assemblies .NET e é usado pelo carregador de assembly .NET para saber qual versão de um assembly carregar/ligar em tempo de execução.

Destes, o único que é absolutamente exigido pelo .NET é o AssemblyVersion atributo.Infelizmente, ele também pode causar mais problemas quando muda indiscriminadamente, especialmente se você tiver nomes fortes para seus assemblies.

Para manter esta questão atual, vale destacar que AssemblyInformationalVersion é usado pelo NuGet e reflete o versão do pacote incluindo qualquer sufixo de pré-lançamento.

Por exemplo, um AssemblyVersion de 1.0.3.* empacotado com o núcleo asp.net dotnet-cli

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

Produz um pacote com versão 1.0.3-ci-7 que você pode inspecionar com reflexão usando:

CustomAttributeExtensions.GetCustomAttribute<AssemblyInformationalVersionAttribute>(asm);

Vale a pena observar algumas outras coisas:

1) Conforme mostrado na caixa de diálogo Propriedades do Windows Explorer para o arquivo de montagem gerado, existem dois locais chamados "Versão do arquivo".Aquele visto no cabeçalho da caixa de diálogo mostra AssemblyVersion, não AssemblyFileVersion.

Na seção Outras informações de versão, há outro elemento chamado "Versão do arquivo".É aqui que você pode ver o que foi inserido como AssemblyFileVersion.

2) AssemblyFileVersion é apenas texto simples.Ele não precisa estar em conformidade com as restrições do esquema de numeração que o AssemblyVersion faz (<build> <65K, por exemplo).Pode ser 3.2.<release tag text>.<datetime>, se desejar.Seu sistema de construção terá que preencher os tokens.

Além disso, não está sujeito à substituição de curinga que AssemblyVersion está.Se você tiver apenas um valor "3.0.1.*" no AssemblyInfo.cs, é exatamente isso que será mostrado no elemento Outras informações da versão-> Versão do arquivo.

3) No entanto, não sei o impacto sobre um instalador ao usar algo diferente de números de versão de arquivo numérico.

Quando a verificação de montagem de uma montagem é alterada, se tiver um nome forte, os assemblies de referência precisam ser recompilados, caso contrário, a montagem não carrega!Se não tiver um nome forte, se não for adicionado explicitamente ao arquivo do projeto, ele não será copiado para o diretório de saída durante a construção, portanto você poderá perder montagens dependentes, especialmente após limpar o diretório de saída.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top