协慌网

登录 贡献 社区

AssemblyVersion,AssemblyFileVersion 和 AssemblyInformationalVersion 之间有什么区别?

有三个程序集版本属性。有什么区别?如果我使用AssemblyVersion并忽略其余部分,这样可以吗?


MSDN 说:


这是使用装配属性的最佳做法的后续行动

答案

的 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) - 向微软报告 (未在 VS2013 中修复)。

AssemblyInformationalVersion是可选的。如果没有给出,则使用 AssemblyFileVersion。

我使用格式: major.minor [revision as string] 。这将导致:

[assembly: AssemblyInformationalVersion("1.0 RC1")]

在. 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 以反映程序集的版本,然后在每次构建系统编译程序集时增加 Build 和 / 或 Revision。 AssemblyFileVersion 应该允许您唯一地标识程序集的构建,以便您可以将其用作调试任何问题的起点。

在我当前的项目中,我们让构建服务器将源代码控制存储库中的变更列表编号编码为 AssemblyFileVersion 的 Build 和 Revision 部分。这允许我们直接从程序集映射到其源代码,用于构建服务器生成的任何程序集(无需在源代码管理中使用标签或分支,或手动保留已发布版本的任何记录)。

此版本号存储在 Win32 版本资源中,在查看程序集的 Windows 资源管理器属性页时可以看到。

CLR 不关心也不检查 AssemblyFileVersion。

AssemblyInformationalVersion旨在表示整个产品的版本

AssemblyInformationalVersion 旨在允许整个产品的一致版本控制,其可能包含许多独立版本的程序集,可能具有不同的版本控制策略,并且可能由不同的团队开发。

“例如,产品的 2.0 版本可能包含多个程序集; 其中一个程序集标记为 1.0 版,因为它是一个新的程序集,并未在同一产品的 1.0 版本中发布。通常,您可以设置此版本号的主要部分和次要部分,以表示产品的公共版本。然后,每次打包完整产品及其所有组件时,都会增加构建和修订部分。“ - Jeffrey Richter,[CLR 通过 C#(第二版)] p。 57

CLR 不关心也不检查 AssemblyInformationalVersion。

AssemblyVersion是 CLR 唯一关注的版本(但它关心整个AssemblyVersion

CLR 使用 AssemblyVersion 绑定到强名称程序集。它存储在构建程序集的 AssemblyDef 清单元数据表中,并存储在引用它的任何程序集的 AssemblyRef 表中。

这非常重要,因为这意味着当您引用强名称程序集时,您将紧密绑定到该程序集的特定 AssemblyVersion。整个 AssemblyVersion 必须与绑定成功完全匹配。例如,如果在构建时引用强名称程序集的 1.0.0.0 版本,但只有该程序集的 1.0.0.1 版本在运行时可用,则绑定将失败! (然后,您必须使用程序集绑定重定向来解决此问题。)

关于整个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'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.

我认为这种混淆的根源可能是因为微软原本打算对完整 AssemblyVersion 的这种严格匹配稍微宽松一点,只匹配 Major 和 Minor 版本部分:

“当加载程序集时,CLR 将自动找到与所请求程序集的主要 / 次要版本匹配的最新安装服务版本。” - Jeffrey Richter,[CLR 通过 C#(第二版)] p。 56

这是 1.0 CLR 的 Beta 1 中的行为,但是此功能在 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 的装载机来说是一个非常受欢迎的改变 - 我不能等待。“- Jeffrey Richter,[CLR 来自 C#(第二版)] p。 164(强调我的)

由于这一变化仍未实施,我认为可以安全地假设微软已经对此意图进行了回溯,现在改变这一点可能为时已晚。我试图在网上搜索以了解这些计划发生了什么,但我找不到任何答案。我仍然想深究它。

所以我给 Jeff Richter 发了电子邮件并直接问他 - 我想如果有人知道发生了什么事,那就是他。

他在一个星期六的早上 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 的 Major / Minor(破坏)和 Build / Revision(非破坏)部分之间进行分离。

底线:仔细考虑何时更改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,其中包含所有有趣的服务信息(它是此版本的 Revision 部分,告诉您正在使用的 Service Pack),同时 AssemblyVersion 已修复为无聊的旧版 2.0.0.0。对 AssemblyVersion 的任何更改都会强制引用 mscorlib.dll 的每个. NET 应用程序针对新版本重新编译!

AssemblyVersion几乎保留在. NET 内部,而AssemblyFileVersion就是 Windows 所见。如果转到位于目录中的程序集的属性并切换到版本选项卡,则会在上面看到AssemblyFileVersion 。如果按版本对文件进行排序,则这就是 Explorer 使用的内容。

AssemblyInformationalVersion映射到 “产品版本”,并且纯粹是 “人类使用”。

AssemblyVersion当然是最重要的,但我也不会跳过AssemblyFileVersion 。如果您没有提供AssemblyInformationalVersion ,编译器会通过剥离版本号的 “revision” 部分并离开 major.minor.build 来为您添加它。