【题外话】

一直以来都对.NET项目中的几个版本号(AssemblyVersion、AssemblyFileVersion、AssemblyInformationalVersion)以及版本号中的Revision和Build有疑问,今儿抽了点时间看了几篇文章,整理一下与大家一起分享下。

【文章索引】

  1. AssemblyVersion与AssemblyFileVersion
  2. AssemblyInformationalVersion
  3. Build与Revision

 

【一、AssemblyVersion与AssemblyFileVersion】

众所周知,.NET项目属性中可以设置两种版本号,一种叫程序集版本(AssemblyVersion),一种叫文件版本(AssemblyFileVersion),在微软的知识库(见相关链接1)中有一篇文章提到了这两个版本号的区别,我大致翻译一下。

Assembly Version:这是在.NET Framework中编译和运行时使用的版本号,使用该版本号定位和加载指定程序集。当你在你的项目中引用了指定的程序集,其版本号将会嵌入到你的项目中。在运行时,CLR通过该版本号加载指定程序集。注意,仅当程序集使用强命名时,才会使用程序集名称、公钥、语言信息以及该版本号查找指定程序集,否则只会根据文件名进行查找。

Assembly File Version:这是在文件系统中给文件的版本号,会在Windows资源管理器中显示。但是,在.NET Framework引用类库时从来不会用到这个版本。

我们可以创建两个项目试试,对于引用没有使用强命名程序集的项目,不论修改Assembly Version还是修改Assembly File Version,都不会出现任何错误;而对于引用了使用强命名程序集的项目,一旦引用的程序集的Assembly Version修改,则会出现如下图所示的错误,导致程序无法运行,而修改Assembly File Version则不会出现任何错误。

所以, 在知识库的文章中,也给出了建议的方法:

如果您在为一个应用程序构建一个很多开发者都在引用的基础程序集,并且这个程序集更新速度非常快,比如一天一次之类的,而且这个程序集还是强命名的,那么您每次更新完程序集后所有的开发者都需要重新更新引用。这样做非常繁琐并且还容易引用出错。所以对于这种情况更好的办法是,固定好Assembly Version,而只修改Assembly File Version,即使用后者来表示最新的版本号。在这种情况下,开发者们不需要更新引用,而仅仅只需要把新的程序集文件覆盖到引用目录下就可以了。在中间或最后发布的版本中,为了更有意义,可以更新Assembly Version,使Assembly File Version与Assembly Version近似。

相关链接2的文章中,作者也给出了修改Assembly Version的情景:

1、当程序集为了维护而更新时,为了向后兼容,一定不要修改Assembly Version。

2、在程序集有重大修改时,一定要修改Assembly Version。

【二、AssemblyInformationalVersion】

除了上述两种版本号外,其实还有一种版本号,可以自己在AssemblyInfo.cs文件中添加,那就是AssemblyInformationalVersion,从名字就可以看出来,这个版本号更大的意义是版本的信息,而不仅仅是数字的描述,比如可以设置为如下的版本信息之类的。

[assembly: AssemblyInformationalVersion("1.0 RC")]

AssemblyInformationalVersion与AssemblyFileVersion一样,都是可以在Windows资源管理器中显示的,换言之,其都是存储在Win32版本资源中的。所以如果不设置AssemblyInformationalVersion的话,默认在文件属性里显示的“产品版本”就是AssemblyFileVersion,而设置了AssemblyInformationalVersion以后,才会显示AssemblyInformationalVersion设置的内容。如下图,左边为未设置AssemblyInformationalVersion,右边为设置了AssemblyInformationalVersion。

【三、Build与Revision】

对于.NET的项目,版本号是由Major.Minor.Build.Revision构成的,通常被称作主要版本、次要版本、内部版本以及修订号。在MSDN上有专门对版本号说明的内容(见相关链接3),比较重要的摘抄如下:

Major:名称相同但主要版本号不同的程序集不可互换。 更高版本号可能表明大幅重写无法假定向后兼容的产品。
Minor:如果两个程序集的名称和主要版本号相同,而次要版本号不同,这指示显著增强,但照顾到了向后兼容性。 该较高的次要版本号可指示产品的修正版或完全向后兼容的新版本。
Build:生成号的不同表示对相同源所作的重新编译。 处理器、 平台或编译器更改时,可能使用不同的生成号。
Revision:名称、主要版本号和次要版本号都相同但修订号不同的程序集应是完全可互换的。 更高修订号可能在修复以前发布的程序集安全漏洞的版本中使用。

程序集的只有Build或Revision不同的后续版本被认为是先前版本的修补程序 (Hotfix) 更新。

在《CLR via C#(第3版)》一书中,也提到了版本号的建议使用方式:

如果公司每天都要生成程序集,那么每天都应该递增这个build号。最后一个编号指出build的修订次数。如果因为某个原因,公司某一天必须生成两次程序集(可能是为了修复一个重大的bug),revision号就应该递增。

Microsoft使用的就是这个版本编号方案,而且建议你也是用它。

P52

【相关链接】

  1. How to use Assembly Version and Assembly File Version:http://support.microsoft.com/kb/556041/en-us
  2. Assembly Versioning in .NET:http://www.danielfortunov.com/software/%24daniel_fortunovs_adventures_in_software_development/2009/03/03/assembly_versioning_in_net
  3. Version 类:http://msdn.microsoft.com/zh-cn/library/system.version.aspx

.NET项目版本号的小随笔的更多相关文章

  1. Mysql查找所有项目开始时间比之前项目结束时间小的项目ID

    这是之前遇到过的一道sql面试题,供参考学习: 查找所有项目开始时间比之前项目结束时间小的项目ID mysql> select * from t2; +----+---------------- ...

  2. css小随笔(二)与通用样式

    51先在学校HTML5已经有半个多月了,然后这个星期做了一个京东的手机网站,接触到了通用样式,下面以京东的手机站为例 这两个就是京东手机站了的不同的两个板块,因为HTML5仅仅只是学完了基本标签跟cs ...

  3. 小随笔:利用Shader实现模型爆炸和沙粒化的效果

    0x00 前言 上一篇小随笔<小随笔:利用Shader给斯坦福兔子长毛和实现雪地效果>中,我和大家聊了聊著名的斯坦福兔子和利用geometry shader实现的一些效果.这篇文章继续沿用 ...

  4. CentOS7.0小随笔——指令基本操作(Part.A)

    与其说是CentOS7.0的小随笔,说老实话,基本指令在每个发行版本的Linux中都基本上是一致的. Part.A部分我们讲述以下四个方面:命令行界面与图形界面.Linux系统的关闭与重启.命令行帮助 ...

  5. 微信小程序项目总结-记账小程序(包括后端)

    一.小程序部分 这是理财系统的前端,江苏海洋大学微信小程序比赛,最后获得了一等奖 GitHub:https://github.com/GeorgeLeoo/finance 1. 项目描述 (1). 此 ...

  6. C#项目版本号自定义位置自动向上增加小工具设计与实现

    自从毕了业,好久没更新了,今天突发奇想,过来更新一下,嘻嘻! 一般在做版本升级时,要锁定版本号进行对比,然后联网检索可用的升级包信息,在用VS做C#项目组件版本管理时,是一个很麻烦的事,每次Relea ...

  7. Java maven项目的小随笔

    1.web.xml里面有filter拦截设置,注意. 2.编译之后,网页中读取资源的路径是apache-tomcat/wtpwebapps/..,若该路径下没有相应资源,则报404错误.

  8. .Net项目版本号的生成

    给.Net项目编译的程序集加入版本号的方式有许多种,包括: 1. 默认的方式,在每个项目的AssemblyInfo.cs文件中指定版本号: // Version information for an ...

  9. java发布项目后注意小点,以及对于金额在java中的处理

    项目在发布之后,有时会进行一些小的地方的修改,特别是对于一些常量的修改,如定义的一些特殊账户,第三方的key值,当修改的时候,我之前就偷懒过,因为项目在服务器上面,访问速度也受到限制,替换整个项目很麻 ...

随机推荐

  1. 【leetcode】Valid Parentheses

    题目简述: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if th ...

  2. F#之旅0 - 开端

    F#之旅0 - 开端 UWP的学习告一段落,CozyRSS的UWP版本并没有做.UWP跟wpf开发几乎一模一样,然后又引入了很多针对移动设备的东西,这部分有点像android.没啥太大的意思,不难,估 ...

  3. git 用不同的邮箱配置不同的ssh

    首先,介绍一下配置背景: 1.有两个邮箱A@mail.com  , B@mail.com 2.两个git账号,一个公司gitlab上的A@mail ,另一个github上的B@mail 3. 目标:提 ...

  4. Learn Git and GitHub without any code!

    What is GitHub? GitHub is a code hosting platform for version control and collaboration.代码托管平台. repo ...

  5. java 对List进行物理分页

    /* * To change this template, choose Tools | Templates * and open the template in the editor. */ pac ...

  6. Puppet自动化部署-前期环境准备(2)

    在安装Puppet环境之前需要配置好机器的基本配置,如规范网络地址IP.hostname,certname认证名称,ntp时间同步等配置完毕,完善的搭建自动化环境. 1.环境介绍 此处实现部署的环境是 ...

  7. 【CentOS】LNMP

    本文为博主JerryChan所有,如需转载,请联系博主747618706@qq.com,并附上博客链接/////////////////目录//////////////////一.LNMP的安装 1. ...

  8. Android -- PopupWindow(其中嵌套ListView 可以被点击)

    1. 效果图

  9. js中自定义构造函数讲解

    什么是构造函数? 构造函数其实就是一个函数,只是用途和普通函数,不太一样, 构造函数一般用于初始化对象 <script> function Person(){ this.name=&quo ...

  10. @dynamic 模拟NSManagedObject类的内部实现,AFN的非常规用法

    @property和@synthesize复习 @property生成setter和getter的声明,同时生成属性对应的成员变量,并且前面加一个下划线_.如果将getter和setter的实现同时重 ...