动态更新.Net项目Build的版本号

来源:互联网 发布:软件报价单 编辑:程序博客网 时间:2024/06/05 01:55

每个.Net项目编译出来的exe或者dll文件都有三个版本,分别是:Assembly Version, File Version 和 Product Version (也叫AssemblyInformationalVersion)。可以点击鼠标右键,然后选择属性里面可以看到。它们的区别可以参考这里:http://stackoverflow.com/questions/64602/what-are-differences-between-assemblyversion-assemblyfileversion-and-assemblyin。

理论上每次构建的版本号都是应该是不一样的,所以这就要求在持续集成环境中能够动态更新软件的版本。Google了一下,找到了这篇文章http://weblogs.asp.net/srkirkland/archive/2010/12/07/simple-msbuild-configuration-updating-assemblies-with-a-version-number.aspx,其不需要安装第三方的插件就能实现我们需要的功能。当然也有其他实现方式。

它的思路是:

1. 把公共的配置参数提取出来(比如版本号),放到一个文件里面(比如CommonAssemblyInfo.cs),然后其他需要动态更改版本号的工程去引用这个文件。这样做的目的是避免重复。

2. 在编译开始的时候,看看有没有版本号传递进来,如果有就去修改CommonAssemblyInfo.cs里面定义的版本号。它是用正则表达式匹配的方式找到需要修改的地方,然后再替换为传递进来的版本号。通常是持续集成服务把版本号传递进来。版本号可以是持续集成中的build号。如果用SVN作为源代码管理工具,也可以将SVN的Revision作为版本号的一部分传递进来,这样就能在二进制文件和源代码之间建立一一对应关系。

不过,该文中的方法在VS2010中有些问题,对应的解决方法如下:

1. 问题:按照文中的方式修改了csproj文件,导致单元测试的工程无法编译。

解决办法:它里面的实现方式是新建了一个名为Go的target,Go再依赖UpdateAssemblyVersion和Build这两个targets。可以尝试去掉Go这个target,直接把默认的target设置为UpdateAssemblyVersion;Build

2. 问题: 在VS2010里面有个警告,提示信息是:The file '..\Build\CommonAssemblyInfo.cs' could not be added to the project.  There is already a link to 'xxx\Build\CommonAssemblyInfo.cs'. A project cannot have more than one link to the same file.

解决办法: 把其中一次引用加上$(MSBuildProjectDirectory)\,这样虽然是引用的同一个文件,但是VS也不认为是同一个文件。因为就是当前工程的目录,所以加上没有任何副作用。


附上我的csproj文件的模板:

<?xml version="1.0" encoding="utf-8"?><Project DefaultTargets="UpdateAssemblyVersion;Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">  <!-- omitted, existing project configuration -->  <Import Project="..\Build\Build.tasks" />  <ItemGroup>    <RegexTransform Include="$(MSBuildProjectDirectory)\..\Build\CommonAssemblyInfo.cs">      <Find>(?<major>\d+)\.(?<minor>\d+)\.\d+\.(?<revision>\d+)</Find>      <ReplaceWith>$(BUILD_NUMBER)</ReplaceWith>    </RegexTransform>  </ItemGroup>  <Target Name="UpdateAssemblyVersion" Condition="'$(BUILD_NUMBER)' != ''">    <RegexTransform Items="@(RegexTransform)" />  </Target></Project>

目录结构是:

\<SolutionRoot>\Build\Build.tasks\<SolutionRoot>\Build\CommonAssemblyInfo.cs\<SolutionRoot><ProjectFolder>\<ProjectName>.csproj