CLR via C# 3 读书笔记(14):第2章 生成、打包、部署和管理应用程序与类型 — 2.5 程序集版本资源信息

当AL.exe或CSC.exe生成PE文件程序集时,还在PE文件中内嵌了一个标准的Win32版本资源。用户可以查看文件属性找到该资源。应用程序代码还可以在运行时调用System.Diagnostics.FileVersionInfo的GetVersionInfo静态方法来得到资源信息。下图显示了JeffTypes.dll属性对话框的Details选项卡。

 image

当生成程序集时,我们应该使用自定义特性来设置其版本资源字段。这些自定义字段应该被应用在程序集级别上。下面的代码将产生如上图所示的版本信息:

using System.Reflection;

// FileDescription version information:
[assembly: AssemblyTitle("JeffTypes.dll")]

// Comments version information:
[assembly: AssemblyDescription("This assembly contains Jeff's types")]

// CompanyName version information:
[assembly: AssemblyCompany("Wintellect")]

// ProductName version information:
[assembly: AssemblyProduct("Wintellect (R) Jeff's Type Library")]

// LegalCopyright version information:
[assembly: AssemblyCopyright("Copyright (c) Wintellect 2010")]

// LegalTrademarks version information:
[assembly:AssemblyTrademark("JeffTypes is a registered trademark of Wintellect")]

// AssemblyVersion version information:
[assembly: AssemblyVersion("3.0.0.0")]

// FILEVERSION/FileVersion version information:
[assembly: AssemblyFileVersion("1.0.0.0")]

// PRODUCTVERSION/ProductVersion version information:
[assembly: AssemblyInformationalVersion("2.0.0.0")]

// Set the Language field (discussed later in the "Culture" section)
[assembly:AssemblyCulture("")]

不幸的是,Windows Explorer属性对话框并不包含上述全部特性。特别是如果能显示AssemblyVersion特性的值就完美了,因为CLR再家在程序集的时候会使用这个值。

下面的表显示了版本资源字段和对应的自定义特性。如果你使用AL.exe生成程序集,你可以使用命令行开关来代替使用自定义特性的方式设置这些信息。表的第二列为每个版本资源字段所对应的AL.exe命令行开关。要注意的是C#编译器没有提供一些命令行开关,因此使用自定义特性来设置这些信息使首选。

版本资源 AL.exe开关 自定义特性/注释
FILEVERSION /fileversion System.Reflection.AssemblyFileVersionAttribute
PRODUCTIVERSION /productversion System.Reflection.AssemblyInformationalVersionAttribute
FILEFLAGSMASK (none) 总是设置为VS_FFI_FILEFLAGSMARK(在WinVer.h中位0x0000003F)
FILEFLAGS (none) 总是为0
FILEOS (none) 目前总是为VOS_WINDOWS32
FILETYPE /target 如果指定为/target:exe或/target:winexe则设置为VFT_APP,如果指定为/target:library,则设置为VFT_DLL
FILESUBTYPE (none) 总是设置为VFT2_UNKNOWN(该字段对于VFT_APP和VFT_DLL来说没有意义)
AssemblyVersion /version System.Reflection.AssemlbyVersionAttribute
Comments /description System.Reflection.AssemblyDescriptionAttribute
CompanyName /company System.Reflection.AssemblyCompanyAttribute
FileDescription /title System.Reflection.AssemblyTitleAttribute
FileVersion /version System.Reflection.AssemblyFileVersionAttribute
InternalName /out 设置为指定的输出文件的名称(不含扩展名)
LegalCopyright /copyright System.Reflection.AssemblyCopyrightAttribute
LegalTrademarks /trademark System.Reflection.AssemblyTrademarkAttribute
OriginalFilename /out 设置为输出文件的名称(不含路径)
PrivateBuild (none) 总是为空白(blank)
ProductName /product System.ReflectionAssemblyProductAttribute
ProductVersion /productversion System.Reflection.AssemblyInformationVersionAttribute
SpecialBuild (none) 总是为空白(blank)

当你在Visual Studio中创建C#项目时,会自动生成一个Assembly.cs文件。该文件包含所有本节所介绍的程序集版本特性,以及一些第3章涵盖的特性。你可以打开AssemblyInfo.cs文件,修改程序集特定的信息。Visual Studio还提供了一个对话框可以对程序集版本信息进行编辑。在Solution Explorer中右击项目属性条目,选择Application选项卡,点击Assembly Infomation,可以看到如下图所示的对话框。

image 

版本号

我们看到一个程序集可以应用多个版本号。这些版本号的格式都使一致的,共包含4个部分。

image[3]

前两个数字组成了版本的公共部分。本例中程序集的公共版本号即为2.5。第三个数字719指明了程序集的生成次数。如果每天都生成程序集,那么这个数字每天都应该增加。最后一个数字2指明了生成的版本。如果由于某些原因(如解决了一个影响其他部分的大bug)在一天内生成了两次,那么应该增加这个数字。

微软使用的就是这种版本号模式,并且也强烈建议大家这么做。未来的CLR版本将对加载新的程序集版本,以及在新版本与当前应用不兼容时回滚到旧版本提供更好的支持。要做到这种版本化支持,CLR要求修补了bug的程序集的版本要有相同的主次版本号,生成和修订版本号要指明包含了更新的服务版本。当加载程序集时,CLR将自动查找最近安装的与主次版本号匹配的程序集的服务版本。

你会发现一个程序集包含三个相关的版本号。这导致了很多混淆。每个版本号的意图和用法如下:

  • AssemblyFileVersion:该版本号存储在Win32版本资源中。它只是一个信息,CLR不检查该版本号。典型地,可以设置主次版本号来标识希望被公众看到的版本。然后每生成一次,就增加生成和修订版本号。理想情况下,微软工具(CSC.exe或AL.exe)会自动更新生成版本号和修订版本号(根据生成的日期和时间),但事实并不是这样。该版本号可以在Windows Explorer中看到,并用来识别指定程序集的版本。
  • AssemblyInformationVersion:该版本号同样保存在Win32版本资源中,也是作为信息存在。CLR既不检查也不关心它。该版本号用来标识包含该程序集的产品的版本。例如,一个产品的2.0版本可能包含多个程序集,其中一个新的程序集由于没有随产品的1.0版本发布而被标识为1.0版本。典型地,我们可以设置该版本号的主次部分来表示产品的公共版本。然后在每次打包成一个完整的产品时,增加版本号的生成和修订部分。
  • AssemblyVersion:该版本号存储在AssemblyDef清单元数据表中。在绑定强命名程序集时,CLR会使用该版本号。它用来唯一标识一个程序集。当开始开发一个程序集时,你需要设置主、次、生成、修订版本号,并且在开始开发程序集的下一个部署版本之前,不应该改变它们。在生成一个程序集时,该程序集所引用的所有程序集的版本号会内嵌到AssemblyRef表的条目中。这意味着一个程序集一个程序集将和它引用的程序集的特定版本紧紧绑定在一起。
posted @ 2010-04-07 15:07  麒麟.NET  阅读(2196)  评论(4编辑  收藏  举报