В чем различия между AssemblyVersion, AssemblyFileVersion и AssemblyInformationalVersion? - PullRequest
822 голосов
/ 15 сентября 2008

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


MSDN говорит:

  • AssemblyVersion

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

  • AssemblyFileVersion

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

  • AssemblyInformationalVersion

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


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

Ответы [ 7 ]

869 голосов
/ 15 сентября 2008

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 [редакция в виде строки] . Это приведет к:

[assembly: AssemblyInformationalVersion("1.0 RC1")]
569 голосов
/ 29 апреля 2009

Управление версиями сборок в .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")]

По соглашению, четыре части версии называются Major Version , Minor Version , Build и Revision .

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

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

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

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

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

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

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

«Например, версия 2.0 продукта может содержать несколько сборок; один из этих сборок помечается как версия 1.0, так как это новая сборка который не поставлялся в версии 1.0 тот же продукт. Как правило, вы устанавливаете основные и второстепенные части этой версии номер для представления публичной версии вашего продукта. Тогда вы увеличиваете части сборки и ревизии каждый раз Вы упаковываете полный продукт с все его сборки ». - Джеффри Рихтер, [CLR через C # (второе издание)] с. 57

CLR не заботится и не проверяет информационную версию Assembly.

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

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

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

Путаница по поводу того, должен ли совпадать весь AssemblyVersion. (Да, это так.)

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

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

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

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

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

Это было поведение в бета-версии 1 CLR 1.0, однако эта функция была удалена до выпуска 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 через C # (второе издание)] с. 164 (Акцент мой)

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

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

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

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

Стоит также отметить из моего дискаИспользование в Jeff, что AssemblyFileVersion был добавлен только после удаления механизма «автоматического отката» - потому что после 1.0 Beta 1 любое изменение в AssemblyVersion было критическим изменением для ваших клиентов, тогда было некуда безопасно хранить ваш номер сборки , AssemblyFileVersion - это безопасное убежище, поскольку оно никогда не проверяется автоматически CLR. Может быть, так будет понятнее, имея два отдельных номера версий с разными значениями, вместо того, чтобы пытаться провести это разделение между основными / второстепенными (разрывными) и сборочными / ревизионными (неразрывными) частями AssemblyVersion.

Итог: тщательно продумайте, когда вы поменяете AssemblyVersion

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

  • Не изменять AssemblyVersion для сервисного выпуска, который предназначен для обратной совместимости.
  • Do изменить 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, которая содержит всю интересную информацию об обслуживании (это версия Revision этой версии, которая сообщает вам, какой пакет обновления у вас установлен), в то время как AssemblyVersion имеет устаревшую версию 2.0.0.0. Любое изменение в AssemblyVersion заставит каждое приложение .NET, ссылающееся на mscorlib.dll, перекомпилироваться для новой версии!

41 голосов
/ 15 сентября 2008

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

AssemblyInformationalVersion соответствует «версии продукта» и предназначен исключительно для использования человеком.

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

21 голосов
/ 15 сентября 2008

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

AssemblyInformationalVersion - это значение «Версия продукта». AssemblyFileVersion - это значение «Версия файла».

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

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

8 голосов
/ 23 июня 2016

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

Например, 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 голосов
/ 28 ноября 2013

Стоит отметить еще кое-что:

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

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

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

Кроме того, не требуется подстановочный символ, которым является AssemblyVersion. Если у вас просто есть значение «3.0.1. *» В AssemblyInfo.cs, это именно то, что будет отображаться в элементе «Другая информация о версии» -> «Версия файла».

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

2 голосов
/ 17 февраля 2012

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

...