elvis0123

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

TFS Build 2010生成构建之 dll、exe文件的版本

 

    TFS Build 2010的生成服务十分的强大,以前的版本号插件现在已经不需要了,直接在生成定义里面做就可以了(参考"TFS 2010 Build中,版本号的定义",具体版本号定义可参考 "软件项目版本号的命名规则及格式介绍(转)")。但是这个方法只能让生成的名称有版本号,如TestInstaller_2.0.21023.1。生成完成后的DLL文件和EXE文件的版本怎样能和这个定义的版本号匹配呢?下面就是我的方法。原创且成功实现,但是一定绕弯了,希望大家能够指正。

PS:有一款生成的插件应该能达到这个效果。不过我没成功,可能因为我的TFS是中文,插件是英文导致的。

 

1 实现原理

DLL和EXE文件的版本都是在Properties文件夹的AssemblyInfo.cs文件下定义的。只要在构建之前将这个文件内的版本相关信息修改,在编译后就可以实现dll的版本号了。

 

    因此,我们大概的流程就是在生成的过程中加入一个环节----生成服务器在完确定版本号、获取源码后对所有的AssemblyInfo.cs文件进行修改,将其版本号修改后再进行生成即可。

 

2 版本号的确定

首先要规定一下版本号的样式。一般来说我们使用

"产品_主版本.次版本.内部版本号.修订号"的方式。因此我们再生成定义中,内部版本号脚本使用此格式

$(BuildDefinitionName)_1.0.1$(Date:MMdd)$(Rev:.r)

 

这里要说明一下。

  • $(BuildDefinitionName) 这个是生成版本的名称。后面用下杠连接版本。
  • 1.0这个是主版本.次版本。由于升级幅度这里不会很频繁,因此采用手工修改
  • 1$(Date:MMdd)这个是内部版本号。本来可以用年月日的。但是经测试,AssemblyInfo这个文件被编译的时候版本号不能使用如20110520这样的版本,而只能使用10520这样的。因此我手动将其修改为一,至少2011年可以了。
  • $(Rev:.r)每次生成的版本,自增1.

 

问题:内部版本号不能在生成定义的时候做计算,如mod,直接使用完整的年月日编译的时候又会出问题。因此只能手工定义。这里如果有人知道如何简单完成。请告知。谢谢!

 

3 修改文件内容的插件制作

    由于没找到相应的方法,我只能调用外部程序,对AssemblyInfo文件进行修改。大概方式就是读取AssemblyInfo文件,正则找到相应位置,将版本号修改为传入的版本号,保存文件。

  • 新建一个C#的控制台程序ModifyVersionInfo

     

  • 定义三个参数
    string FilePath = args[0].ToString();//接收文件地址 

    string AssemblyVersion = args[1].ToString(); 

    string AssemblyFileVersion = args[2].ToString(); 

 

  • 去掉只读属性(必须,获取的源码皆为只读)
    File.SetAttributes(FilePath,FileAttributes.Normal); 

 

  • 读取文件
    FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read); 

    StreamReader SR 
    = new StreamReader(fs, System.Text.Encoding.Default); 

    SR.BaseStream.Seek(
    0, SeekOrigin.Begin); 

    string strLine = SR.ReadToEnd(); 

    SR.Close(); 

    fs.Close(); 

 

  • 修改文件
    string OutputFile; 

    //替换AssemblyVersion 

    OutputFile 
    = Regex.Replace(strLine, "\\[assembly: AssemblyVersion.*?\\]""[assembly: AssemblyVersion(\"" + AssemblyVersion + "\")]", RegexOptions.IgnoreCase); 

     

    //替换AssemblyFileVersion 

    OutputFile 
    = Regex.Replace(OutputFile, "\\[assembly: AssemblyFileVersion.*?\\]""[assembly: AssemblyFileVersion(\"" + AssemblyFileVersion + "\")]", RegexOptions.IgnoreCase); 

 

  • 重写文件
    FileStream fs2 = new FileStream(FilePath, FileMode.Create, FileAccess.Write); 

    StreamWriter SW 
    = new StreamWriter(fs2, System.Text.Encoding.Default); 

    SW.Flush(); 

    SW.WriteLine(OutputFile); 

    SW.Close(); 

    fs2.Close(); 

 

这样,我们再执行一个修改的时候的方式是

ModifyVersionInfo.exe x:\ AssemblyInfo.cs 2.0.1520.1 2.0.1520.1

 

附源代码:

 

4 修改生成流程

4.1 查找AssemblyInfo文件

    编辑"DefaultTemplate.xaml"文件,双击"RunOnAgent"过程。点击变量,新建一个变量"AllAssemblyInfoFiles",其类型为"IEnumerable<String>"用于存储AssemblyInfo文件路径列表。

 

在If CreatLabel过程后拖入一个"FindMatchingFiles"并改名为"FindAssemblyInfoFiles"

    编辑MatchingPattern如下

    Sting.Format(SourcesDirectory + "\**\assemblyinfo.cs")

    编辑Result如下

    AllAssemblyInfoFiles

4.2 修改文件

    在FindAssemblyInfoFiles的后面拖入一个ForEach的循环。将其Values改为"AllAssemblyInfoFiles"

 

    双击进入ForEach循环,在其中放入一个"Sequence",并取名为"ModifyAssemblyInfoFile"

 

    双击进入ModifyAssemblyInfoFile。放入一个"InvokeProcess"取名为"ModifyAssemblyInfoFile"

 

修改Argument为:

String.Format(item.ToString() + " " + BuildDetail.BuildNumber.Substring(BuildDetail.BuildNumber.IndexOf("_") + 1, BuildDetail.BuildNumber.Length - BuildDetail.BuildNumber.IndexOf("_") - 1) + " " + BuildDetail.BuildNumber.Substring(BuildDetail.BuildNumber.IndexOf("_") + 1, BuildDetail.BuildNumber.Length - BuildDetail.BuildNumber.IndexOf("_") - 1))

 

FileName为(插件的放置位置—在生成服务器上):

String.Format("c:\ModifyVersionInfo.exe")

 

保存即可

5 生成测试

生成后可以看到版本号已被修改

 

posted on 2011-05-20 12:22  elvis  阅读(934)  评论(2编辑  收藏  举报