Каковы различия между AssemblyVersion, AssemblyFileVersion и AssemblyInformationalVersion?

Существует три атрибута сборки. Каковы различия? Это нормально, если я использую AssemblyVersion и игнорирую остальные?


MSDN говорит:

  • AssemblyVersion:

    Указывает версию приписываемой сборки.

  • AssemblyFileVersion:

    Поручает компилятору использовать определенный номер версии для ресурса версии файла Win32. Версия файла Win32 не обязательно должна совпадать с номером версии сборки.

  • AssemblyInformationalVersion:

    Определяет дополнительную информацию о версии для манифеста сборки.


Это продолжение: Каковы наилучшие методы использования ассемблеров Ассамблеи?

Ответ 1

AssemblyVersion

Где будут смотреться другие сборки, которые ссылаются на вашу сборку. Если это число изменится, другие сборки должны обновить свои ссылки на вашу сборку! Требуется AssemblyVersion.

Я использую формат: major.minor. Это приведет к:

[assembly: AssemblyVersion("1.0")]

AssemblyFileVersion

Используется для развертывания. Вы можете увеличить этот номер для каждого развертывания. Он используется программами установки. Используйте его для обозначения сборок с тем же AssemblyVersion, но сгенерированы из разных сборников.

В Windows его можно просмотреть в свойствах файла.

Если возможно, пусть он будет создан MSBuild. AssemblyFileVersion не является обязательным. Если не задано, используется AssemblyVersion.

Я использую формат: major.minor.revision.build, где я использую ревизию для этапа разработки (Alpha, Beta, RC и RTM), пакеты обновлений и исправления. Это приведет к:

[assembly: AssemblyFileVersion("1.0.3100.1242")]

AssemblyInformationalVersion

Версия продукта сборки. Это версия, которую вы использовали бы при разговоре с клиентами или для показа на вашем веб-сайте. Эта версия может быть строкой, например, "1.0 Release Candidate".

Анализ кода будет жаловаться на это (CA2243) - сообщенный Microsoft (не фиксированный в VS2013).

AssemblyInformationalVersion не является обязательным. Если не указано, используется AssemblyFileVersion.

Я использую формат: major.minor [revision as string]. Это приведет к:

[assembly: AssemblyInformationalVersion("1.0 RC1")]

Ответ 2

Вершина сборки в.NET может быть запутанной перспективой, учитывая, что в настоящее время существует как минимум три способа указать версию для вашей сборки.

Вот три основных атрибута сборки, связанные с версией:

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

По соглашению, четыре части версии называются основной версией, малой версией, сборкой и ревизией.

AssemblyFileVersion предназначена для уникальной идентификации сборки отдельной сборки

Обычно вы вручную устанавливаете Major и Minor AssemblyFileVersion, чтобы отразить версию сборки, а затем увеличивайте сборку и/или ревизию каждый раз, когда ваша система сборки компилирует сборку. AssemblyFileVersion должен позволить вам однозначно идентифицировать сборку сборки, чтобы вы могли использовать ее в качестве отправной точки для отладки любых проблем.

В моем текущем проекте у нас есть сервер сборки, который кодирует номер списка изменений из нашего исходного хранилища управления в части сборки и пересмотра AssemblyFileVersion. Это позволяет нам напрямую сопоставлять сборку с исходным кодом для любой сборки, сгенерированной сервером сборки (без необходимости использования меток или ветвей в исходном элементе управления или для ведения любых записей выпущенных версий вручную).

Этот номер версии хранится в ресурсе версии Win32 и может быть замечен при просмотре страниц свойств проводника Windows для сборки.

CLR не заботится и не рассматривает AssemblyFileVersion.

AssemblyInformationalVersion предназначена для представления версии всего вашего продукта

AssemblyInformationalVersion предназначен для обеспечения согласованного управления версиями всего продукта, который может состоять из многих сборок, которые независимо версируются, возможно, с разными политиками управления версиями и потенциально разрабатываются разрозненными командами.

Например, версия 2.0 продукта может содержать несколько сборок: одна из этих сборок помечена как версия 1.0, так как ее новая сборка, которая не была отправлена в версии 1.0 того же продукта. Обычно вы устанавливаете основную и второстепенную части этого номер версии для представления общедоступной версии вашего продукта. Затем вы увеличиваете детали сборки и ревизии каждый раз, когда вы упаковываете полный продукт со всеми его сборками ". - Джеффри Рихтер, [CLR через С# (второе издание)] стр. 57

CLR не заботится и не рассматривает AssemblyInformationalVersion.

AssemblyVersion - единственная версия, с которой заботится CLR (но она заботится о всей AssemblyVersion)

AssemblyVersion используется CLR для привязки к сильно названным сборкам. Он хранится в таблице метаданных манифеста AssemblyDef встроенной сборки и в таблице AssemblyRef любой сборки, которая ссылается на нее.

Это очень важно, потому что это означает, что когда вы ссылаетесь на сильно названную сборку, вы тесно связаны с конкретной AssemblyVersion этой сборки. Весь AssemblyVersion должен быть точным совпадением для успешной привязки. Например, если вы ссылаетесь на версию 1.0.0.0 сильно названной сборки во время сборки, но только версия 1.0.0.1 этой сборки доступна во время выполнения, привязка не удастся! (Затем вам придется обойти это с помощью перенаправления привязки сборок.)

Путаница в отношении соответствия всей AssemblyVersion. (Да.)

Существует немного путаницы вокруг того, должно ли все AssemblyVersion быть точным совпадением, чтобы сборка была загружена. Некоторые люди находятся под ложным убеждением, что только основные и второстепенные части AssemblyVersion должны соответствовать, чтобы привязка к успеху. Это разумное предположение, однако в конечном итоге оно неверно (как и для.NET 3.5), и его тривиально проверить это для вашей версии CLR. Просто выполните этот пример кода.

На моей машине вторая сборка загружается, и последние две строки журнала слияния дают понять, почему:

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

Я думаю, что источником этой путаницы, вероятно, является то, что Microsoft изначально планировала быть немного более мягким в отношении этого строгого соответствия всей AssemblyVersion, сопоставляя только части Major и Minor:

"При загрузке сборки CLR автоматически найдет последнюю установленную версию обслуживания, которая соответствует основной/младшей версии запрашиваемой сборки". - Джеффри Рихтер, [CLR через С# (второе издание)] стр. 56

Это было поведение в Beta 1 из 1.0 CLR, однако эта функция была удалена до версии 1.0 и не смогла перекраиваться в.NET 2.0:

"Примечание. Я только что описал, как вы должны думать о номерах версий. К сожалению, CLR не обрабатывает номера версий таким образом. [В.NET 2.0] CLR рассматривает номер версии как непрозрачное значение, и если сборка зависит от версии 1.2.3.4 другой сборки, CLR пытается загрузить только версию 1.2.3.4 (если перенаправление привязки не на месте). Однако Microsoft планирует изменить загрузчик CLR в будущей версии, чтобы загрузить последнюю версию сборки/пересмотр для данной основной/младшей версии сборки. Например, на будущую версию CLR, если загрузчик пытается найти версию 1.2.3.4 сборки в версии 1.2.5.0 и существует, загрузчик с автоматически подобрать последняя версия обслуживания. Это будет очень приятное изменение для загрузчика CLR - я для одного ожидания не могу. " - Джеффри Рихтер, [CLR через С# (второе издание)] стр. 164 (Акцент мой)

Поскольку это изменение все еще не реализовано, я думаю, что можно с уверенностью предположить, что Microsoft отследила это намерение, и, возможно, уже слишком поздно менять это сейчас. Я попытался найти в Интернете, чтобы узнать, что произошло с этими планами, но я не мог найти ответы. Я все еще хотел разобраться.

Поэтому я отправил по электронной почте Джеффу Рихтеру и спросил его прямо - я подумал, может ли кто-нибудь узнать, что случилось, это был бы он.

Он ответил в течение 12 часов, в субботу утром, не менее, и пояснил, что загрузчик.NET 1.0 Beta 1 реализовал этот "автоматический механизм перемотки вперед, чтобы собрать новейшие доступные сборки и ревизии сборки, но это поведение было отменено перед отправкой.NET 1.0. Позже это было предназначено, чтобы оживить это, но он не сделал это до того, как CLR 2.0 отправлен. Затем появился Silverlight, который стал приоритетом для команды CLR, поэтому эта функциональность затянулась еще дальше. В то же время большинство людей, которые были во времена CLR 1.0 Beta 1, с тех пор переехали, поэтому маловероятно, что это увидит свет дня, несмотря на всю тяжелую работу, которая уже была вложена в нее.

Нынешнее поведение, похоже, здесь, чтобы остаться.

Также стоит отметить из моего обсуждения с Джеффом, что AssemblyFileVersion была добавлена только после удаления "автоматического механизма перемотки вперед", потому что после 1.0 Beta 1 любое изменение в AssemblyVersion стало изменением для ваших клиентов, тогда нигде не было для безопасного хранения вашего номера сборки. AssemblyFileVersion - это безопасное убежище, поскольку оно никогда не проверяется автоматически CLR. Возможно, это более ясное, имея два отдельных номера версии, с отдельными значениями, вместо того, чтобы пытаться сделать это разделение между Major/Minor (break) и Build/Revision (неразрывными) частями AssemblyVersion.

Суть: подумайте о том, когда вы измените свою AssemblyVersion

Мораль заключается в том, что если вы отправляете сборки, которые другие разработчики будут ссылаться, вы должны быть очень осторожны, когда вы это сделаете (и не измените) AssemblyVersion этих сборок. Любые изменения в AssemblyVersion будут означать, что разработчикам приложений придется либо перекомпилировать новую версию (обновить записи AssemblyRef), либо использовать переадресацию связывания сборок, чтобы вручную переопределить привязку.

  • Не меняйте AssemblyVersion для сервисной версии, которая предназначена для обратной совместимости.
  • Как изменить AssemblyVersion для выпуска, что вы знаете, нарушение изменений.

Просто взгляните на атрибуты версии 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")]

Обратите внимание, что его AssemblyFileVersion, которая содержит всю интересную информацию об обслуживании (ее часть версии этой версии, которая сообщает вам, что Service Pack youre), тем временем AssemblyVersion фиксируется в скучном старом 2.0.0.0. Любые изменения в AssemblyVersion заставят каждое приложение.NET ссылаться на mscorlib.dll на повторную компиляцию с новой версией!

Ответ 3

AssemblyVersion в значительной степени остается внутри .NET, а AssemblyFileVersion - это то, что видит Windows. Если вы перейдете к свойствам сборки, сидящей в каталоге, и перейдите на вкладку версии, AssemblyFileVersion будет тем, что вы увидите вверху. Если вы сортируете файлы по версии, это то, что используется Explorer.

AssemblyInformationalVersion отображается в "Версии продукта" и подразумевается исключительно "человеком".

AssemblyVersion, безусловно, самый важный, но я бы тоже не пропустил AssemblyFileVersion. Если вы не предоставили AssemblyInformationalVersion, компилятор добавит его для вас, удалив часть "ревизии" вашего номера версии и оставив файл major.minor.build.

Ответ 4

AssemblyInformationalVersion и AssemblyFileVersion отображаются при просмотре информации о версии в файле через проводник Windows путем просмотра свойств файла. Эти атрибуты фактически скомпилируются в ресурс VERSION_INFO, созданный компилятором.

AssemblyInformationalVersion - это значение "Product version". AssemblyFileVersion - это значение "Версия файла".

AssemblyVersion специфичен для сборников .NET и используется загрузчиком сборки .NET, чтобы узнать, какую версию сборки загружать/связывать во время выполнения.

Из них единственным, что абсолютно необходимо .NET, является атрибут AssemblyVersion. К сожалению, это может также вызвать большинство проблем, когда оно изменяется без разбора, особенно если вы сильно назовете свои сборки.

Ответ 5

Стоит отметить некоторые другие вещи:

1) Как показано в диалоговом окне "Свойства проводника Windows" для сгенерированного файла сборки, есть два места "Версия файла". Тот, который отображается в заголовке диалогового окна, показывает AssemblyVersion, а не AssemblyFileVersion.

В разделе "Информация о другой версии" есть еще один элемент "Версия файла". Здесь вы можете увидеть, что было введено как AssemblyFileVersion.

2) AssemblyFileVersion - это просто текст. Он не должен соответствовать ограничениям схемы нумерации, которые делает AssemblyVersion (<build> < 65K, например). Это может быть 3.2. < текст тега релиза > . <datetime> , если хотите. Ваша система сборки должна будет заполнить токены.

Кроме того, он не подлежит замене шаблонов, что AssemblyVersion. Если у вас есть значение "3.0.1. *" В AssemblyInfo.cs, это именно то, что будет показано в элементе "Информация о другой версии" → "Файл".

3) Я не знаю, как влияет на установщика использование чего-то другого, кроме числовых номеров версий файлов.

Ответ 6

Чтобы сохранить этот вопрос актуальным, стоит подчеркнуть, что AssemblyInformationalVersion используется NuGet и отражает версию пакета, включая любой суффикс предварительной версии.

Например, AssemblyVersion версии 1.0.3. *, упакованная с ядром asp.net dotnet-cli

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

Создает пакет с версией 1.0.3-ci-7, который вы можете проверить с помощью:

CustomAttributeExtensions.GetCustomAttribute<AssemblyInformationalVersionAttribute>(asm);

Ответ 7

Когда сборка AssemblyVersion изменяется, Если у него есть сильное имя, реферирующие сборки необходимо перекомпилировать, иначе сборка не загружается! Если у него нет сильного имени, если он явно не добавлен в файл проекта, он не будет скопирован для вывода каталога при сборке, поэтому вы можете пропустить определенные сборки, особенно после очистки выходного каталога.