2008-10-21 46 views
8

我有要求將多個Web安裝項目(使用VS2005和ASP.Net/C#)安裝到同一個虛擬文件夾中。這些項目共享一些程序集引用(文件系統都被構造爲使用相同的'bin'文件夾),因此如果當前安裝的版本比MSI。僅當程序集發生更改時,我如何才能使用MSBuild更新版本信息?

我不是在暗示悲觀的安裝方案是錯誤的 - 只是它在我接受過的環境中創建了一個問題。由於有相當數量的常用程序集和大量開發人員可能會更改普通程序集,但忘記更新其版本號,試圖手動管理版本控制最終會導致安裝時產生大量混淆。

關於這個問題的另一面,它也是重要的是不要自發更新版本號與更換所有常見的組件安裝,因爲那裏實際進行了更改,可能(至少暫時)模糊的情況。

也就是說,我正在尋找的是隻有在程序集組件(代碼模塊,資源等)已經/實際更改的情況下才更新程序集版本信息(最好使用MSBuild)的方法。

我發現幾個至少部分相關的參考文獻here(MSDN上的AssemblyInfo任務)和here(看起來類似於我需要的,但超過兩年,沒有明確的解決方案)。

我的團隊也使用TFS版本控制,因此自動化解決方案應該可能包含一種方法,通過該方法可以在構建過程中檢出/檢入AssebmlyInfo。

任何幫助將不勝感激。

在此先感謝。

回答

10

我無法回答你所有的問題,因爲我沒有使用TFS的經驗。

但是我可以推薦一個比使用AssemblyInfo任務更好的方法來更新您的AssemblyInfo.cs文件。該任務似乎只是從頭開始重新創建標準AssemblyInfo文件,並丟失了您可能添加的任何自定義部分。

因此,我建議您查看一下MSBuild社區任務項目中的FileUpdate任務。它可以尋找特定的內容在文件中,並取代它,像這樣:

<FileUpdate 
Files="$(WebDir)\Properties\AssemblyInfo.cs" 
Regex="(\d+)\.(\d+)\.(\d+)\.(\d+)" 
ReplacementText="$(Major).$(ServicePack).$(Build).$(Revision)" 
Condition="'$(Configuration)' == 'Release'" 
/> 

有幾種方法可以控制內部版本號的遞增。因爲我只希望構建號碼增加,如果構建完全成功,我使用兩步法:

  • 從文本文件中讀取一個數字(文件中唯一的數字)並添加1而不更改文件;
  • 作爲構建過程的最後一步,如果一切都成功了,請將增加的數字保存迴文本文件。

有任務,如ReadLinesFromFile,可以幫助你這一點,但我發現它最容易寫一個小的自定義任務:

using System; 
using System.IO; 
using Microsoft.Build.Framework; 
using Microsoft.Build.Utilities; 

namespace CredibleCustomBuildTasks 
{ 
    public class IncrementTask : Task 
    { 
     [Required] 
     public bool SaveChange { get; set; } 

     [Required] 
     public string IncrementFileName { get; set; } 

     [Output] 
     public int Increment { get; set; } 

     public override bool Execute() 
     { 
      if (File.Exists(IncrementFileName)) 
      { 
       string lines = File.ReadAllText(IncrementFileName); 
       int result; 
       if(Int32.TryParse(lines, out result)) 
       { 
        Increment = result + 1; 
       } 
       else 
       { 
        Log.LogError("Unable to parse integer in '{0}' (contents of {1})"); 
        return false; 
       } 
      } 
      else 
      { 
       Increment = 1; 
      } 

      if (SaveChange) 
      { 
       File.Delete(IncrementFileName); 
       File.WriteAllText(IncrementFileName, Increment.ToString()); 
      } 
      return true; 
     } 
    } 
} 

我用這個FileUpdateTask之前得到的未來建設數量:

<IncrementTask 
IncrementFileName="$(BuildNumberFile)" 
SaveChange="false"> 
    <Output TaskParameter="Increment" PropertyName="Build" /> 
</IncrementTask> 

和我的最後一步,在構建(通知其他前):

<IncrementTask 
IncrementFileName="$(BuildNumberFile)" 
SaveChange="true" 
Condition="'$(Configuration)' == 'Release'" /> 

如何更新,只有當源代碼已經改變了版本號你的另一個問題是高度依賴於您的構建過程中你是如何與你的源代碼控制交互。通常,檢入源文件更改應啓動持續集成構建。這是用來更新相關版本號的人。

0

我寫了一個custome任務,你可以參考下面的代碼。這將創建一個實用程序,您可以通過集信息路徑主要,次要和版本號。您可以修改它以獲取修訂號。因爲在我的情況下,這個任務是由開發商做我用來搜索,並再次更換整個字符串。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Text.RegularExpressions; 

namespace UpdateVersion 
{ 
    class SetVersion 
    { 
     static void Main(string[] args) 
     { 
      String FilePath = args[0]; 
      String MajVersion=args[1]; 
      String MinVersion = args[2]; 
      String BuildNumber = args[3]; 
      string RevisionNumber = null; 

      StreamReader Reader = File.OpenText(FilePath); 
      string contents = Reader.ReadToEnd(); 
      Reader.Close(); 

      MatchCollection match = Regex.Matches(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", RegexOptions.IgnoreCase); 
      if (match[0].Value != null) 
      { 
       string strRevisionNumber = match[0].Value; 

       RevisionNumber = strRevisionNumber.Substring(strRevisionNumber.LastIndexOf(".") + 1, (strRevisionNumber.LastIndexOf("\"")-1) - strRevisionNumber.LastIndexOf(".")); 

       String replaceWithText = String.Format("[assembly: AssemblyVersion(\"{0}.{1}.{2}.{3}\")]", MajVersion, MinVersion, BuildNumber, RevisionNumber); 
       string newText = Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replaceWithText); 

       StreamWriter writer = new StreamWriter(FilePath, false); 
       writer.Write(newText); 
       writer.Close(); 
      } 
      else 
      { 
       Console.WriteLine("No matching values found"); 
      } 
     } 
    } 
} 
0

我不想說這個,但看起來你可能會做錯的。就是如果你做動態生成的,而不是試圖修補它們裝配的版本要容易得多。

看看https://sbarnea.com/articles/easy-windows-build-versioning/

我爲什麼認爲你做錯了? * A構建不應該修改版本號 *如果你建立同樣的變更兩次,你應該得到相同的版本號 *如果你把內部建立微軟稱之爲集結號號(正確命名是補丁級別),你最終會達到65535的限制。