2013-03-05 90 views
9

我正在使用安裝項目發佈我的項目。我希望每個項目的版本與安裝版本相同。使用MSI安裝版本設置AssemblyInfo版本號

我想在Visual Studio中更改我的安裝版本屬性,並且在構建完成後,要從此屬性更新所有項目版本,這可能嗎?

+1

什麼是「設置版本」? – 2013-03-07 17:11:06

+0

@SimonMourier最初讓我感到困惑,它的第二張截圖顯示在我的答案中。 – 2013-03-10 06:46:09

+0

哦,就我所知,安裝項目的這個「版本」屬性沒有寫在最終的MSI文件中,所以有什麼意義? – 2013-03-10 07:55:19

回答

26

項目大會&文件的版本號:(未安裝的版本,我按編輯你的問題) enter image description here

答1:

如果你想設置的程序集的安裝項目版本號&您需要使用由構建觸發的腳本/ exe來完成文件版本號。

enter image description here

本文就How To Update Assembly Version Number Automatically顯示一半的解決方案......

從研究,我做到了不可能使用SetupVersion在PreBuildEvent。沒有爲它$ SetupVersion命令:http://msdn.microsoft.com/en-us/library/42x5kfw4(v=vs.80).aspx

不必更改PreBuildEvent每個構建與使用-set:命令代碼項目的文章中顯示在this comment並不理想。

我們需要的解決方案是一個PreBuildEvent來調用AssemblyInfoUtil.exe並讓它讀取vdproj項目文件中的「ProductVersion」。然後更新程序集版本號。

我已經修改了代碼的文章向您展示如何讀取來自Setup.vdproj的產品版本,這是它如何從一個PreBuildEvent被稱爲:

AssemblyInfoUtil.exe -setup:"C:\Program Files\MyProject1\Setup1\Setup1.vdproj" -ass:"C:\Program Files\MyProject1\AssemblyInfo.cs" 

這是修改後的代碼:

using System; 
using System.IO; 
using System.Text; 

namespace AssemblyInfoUtil 
{ 
    class AssemblyInfoUtil 
    { 
    private static int incParamNum = 0;  
    private static string fileName = ""; 
    private static string setupfileName = "";  
    private static string versionStr = null;  
    private static bool isVB = false; 
    [STAThread] 
    static void Main(string[] args) 
    { 
     for (int i = 0; i < args.Length; i++) { 
      if (args[i].StartsWith("-setup:")) { 
      string s = args[i].Substring("-setup:".Length); 
      setupfileName = int.Parse(s); 
      } 
      else if (args[i].StartsWith("-ass:")) { 
      fileName = args[i].Substring("-ass:".Length); 
      } 
     } 

     //Jeremy Thompson showing how to detect "ProductVersion" = "8:1.0.0" in vdproj 
     string setupproj = System.IO.File.ReadAllText(setupfileName); 
     int startPosOfProductVersion = setupproj.IndexOf("\"ProductVersion\" = \"") +20; 
     int endPosOfProductVersion = setupproj.IndexOf(Environment.NewLine, startPosOfProductVersion) - startPosOfProductVersion; 
     string versionStr = setupproj.Substring(startPosOfProductVersion, endPosOfProductVersion); 
     versionStr = versionStr.Replace("\"", string.Empty).Replace("8:",string.Empty); 

     if (Path.GetExtension(fileName).ToLower() == ".vb") 
     isVB = true; 

     if (fileName == "") { 
     System.Console.WriteLine("Usage: AssemblyInfoUtil 
      <path to :Setup.vdproj file> and <path to AssemblyInfo.cs or AssemblyInfo.vb file> [options]"); 
     System.Console.WriteLine("Options: "); 
     System.Console.WriteLine(" -setup:Setup.vdproj file path"); 
     System.Console.WriteLine(" -ass:Assembly file path"); 
     return; 
     } 

     if (!File.Exists(fileName)) { 
     System.Console.WriteLine 
      ("Error: Can not find file \"" + fileName + "\""); 
     return; 
     } 

     System.Console.Write("Processing \"" + fileName + "\"..."); 
     StreamReader reader = new StreamReader(fileName); 
      StreamWriter writer = new StreamWriter(fileName + ".out"); 
     String line; 

     while ((line = reader.ReadLine()) != null) { 
     line = ProcessLine(line); 
     writer.WriteLine(line); 
     } 
     reader.Close(); 
     writer.Close(); 

     File.Delete(fileName); 
     File.Move(fileName + ".out", fileName); 
     System.Console.WriteLine("Done!"); 
    } 

    private static string ProcessLine(string line) { 
     if (isVB) { 
     line = ProcessLinePart(line, "<Assembly: AssemblyVersion(\""); 
     line = ProcessLinePart(line, "<Assembly: AssemblyFileVersion(\""); 
     } 
     else { 
     line = ProcessLinePart(line, "[assembly: AssemblyVersion(\""); 
     line = ProcessLinePart(line, "[assembly: AssemblyFileVersion(\""); 
     } 
     return line; 
    } 

    private static string ProcessLinePart(string line, string part) { 
     int spos = line.IndexOf(part); 
     if (spos >= 0) { 
     spos += part.Length; 
     int epos = line.IndexOf('"', spos); 
     string oldVersion = line.Substring(spos, epos - spos); 
     string newVersion = ""; 
     bool performChange = false; 

     if (incParamNum > 0) { 
      string[] nums = oldVersion.Split('.'); 
      if (nums.Length >= incParamNum && nums[incParamNum - 1] != "*") { 
      Int64 val = Int64.Parse(nums[incParamNum - 1]); 
      val++; 
      nums[incParamNum - 1] = val.ToString(); 
      newVersion = nums[0]; 
      for (int i = 1; i < nums.Length; i++) { 
       newVersion += "." + nums[i]; 
      } 
      performChange = true; 
      } 
     } 

     else if (versionStr != null) { 
      newVersion = versionStr; 
      performChange = true; 
     } 

     if (performChange) { 
      StringBuilder str = new StringBuilder(line); 
      str.Remove(spos, epos - spos); 
      str.Insert(spos, newVersion); 
      line = str.ToString(); 
     } 
     } 
     return line; 
    } 
    } 
} 

答2:

我認爲更好的方法是使用Shared Assembly Info類而不是單獨的AssemblyInfo類文件。

要實現此目的,請在名爲SharedAssemblyInfo.cs的解決方案文件夾中創建一個文件,然後將每個項目中的鏈接添加到SharedAssemblyInfo.cs。您還可以將鏈接的SharedAssemblyInfo.cs移動到Properties文件夾中,以便它與AssemblyInfo並排放置。cs是特定於解決方案中的每個項目的,如下所示。

enter image description here

下面是一個示例SharedAssemblyInfo.cs文件:

using System; 
using System.Reflection; 
using System.Runtime.CompilerServices; 
using System.Runtime.InteropServices; 

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information 
// associated with an assembly. 
[assembly: AssemblyCompany("Saint Bart Technologies")] 
[assembly: AssemblyProduct("Demo")] 
[assembly: AssemblyCopyright("Copyright ? Saint Bart 2013")] 
[assembly: AssemblyTrademark("")] 

// Make it easy to distinguish Debug and Release (i.e. Retail) builds; 
// for example, through the file properties window. 
#if DEBUG 
[assembly: AssemblyConfiguration("Debug")] 
[assembly: AssemblyDescription("Flavor=Debug")] // a.k.a. "Comments" 
#else 
[assembly: AssemblyConfiguration("Retail")] 
[assembly: AssemblyDescription("Flavor=Retail")] // a.k.a. "Comments" 
#endif 

[assembly: CLSCompliant(true)] 

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components. If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type. 
[assembly: ComVisible(false)] 

// Note that the assembly version does not get incremented for every build 
// to avoid problems with assembly binding (or requiring a policy or 
// <bindingRedirect> in the config file). 
// 
// The AssemblyFileVersionAttribute is incremented with every build in order 
// to distinguish one build from another. AssemblyFileVersion is specified 
// in AssemblyVersionInfo.cs so that it can be easily incremented by the 
// automated build process. 
[assembly: AssemblyVersion("1.0.0.0")] 

// By default, the "Product version" shown in the file properties window is 
// the same as the value specified for AssemblyFileVersionAttribute. 
// Set AssemblyInformationalVersionAttribute to be the same as 
// AssemblyVersionAttribute so that the "Product version" in the file 
// properties window matches the version displayed in the GAC shell extension. 
[assembly: AssemblyInformationalVersion("1.0.0.0")] // a.k.a. "Product version" 

下面是一個示例AssemblyInfo.cs文件:

// Note: Shared assembly information is specified in SharedAssemblyInfo.cs 
using System.Reflection; 
using System.Runtime.CompilerServices; 
using System.Runtime.InteropServices; 
// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information 
// associated with an assembly. 
[assembly: AssemblyTitle("WindowsFormsApplication2")] 
// The following GUID is for the ID of the typelib if this project is exposed to COM 
[assembly: Guid("ffded14d-6c95-440b-a45d-e1f502476539")] 

所以每次你想改變所有項目大會信息,你可以在一個地方做到這一點。我假設你想將MSI安裝版本設置爲與組件版本號相同,一個手動步驟。


答3:

考慮切換到使用MSBuild它擁有所有這些類型的好處,但我不知道,如果你有時間去把它撿起來,現在。


答4:

組件可自動遞增使用的AssemblyInfo.cs中的以下星號語法的內部版本號:

[assembly: AssemblyVersion("1.0.0.*")] 

這是一個很好的方法,因爲跟蹤內部版本號的點是 ,以便能夠識別不同的版本。由於構建尚未發生,因此預構建版本變化 構建編號會失敗此目的。


答5:

其他CodeProject答案在這裏假定要更新在安裝MSI項目文件ProductVersion, ProductCode, PackageCode。我沒有理解你的問題這種方式,並根據這個線索有問題: pre-build event to change setup project's ProductVersion doesn't take effect until after the build

答6(新):

有幾個TFS構建插件設置「大會信息」: https://marketplace.visualstudio.com/items?itemName=bleddynrichards.Assembly-Info-Task https://marketplace.visualstudio.com/items?itemName=bool.update-assembly-info https://marketplace.visualstudio.com/items?itemName=ggarbuglia.setassemblyversion-task

+0

大答案改變我自己的項目建立正式的方式,但我已經找到了答案1的代碼示例中的一些問題目前沒有需要解析參數傳遞給整的SetupfileName(編譯錯誤)和versionStr不應該被重新聲明爲一個局部變量(使腳本無所事事,沒有任何錯誤!)。 – 2017-03-28 13:41:27

1

我不知道這是否完美地解決您的問題,但你可以實現一個通用類所有configmanagment信息,如:

public class VersionInfo{ 
    public const string cProductVersion = "1.0.0" 
    //other version info 
} 

後,您可以更新與新課程的所有的AssemblyInfo.cs :

[assembly: AssemblyVersion(VersionInfo.cProductVersion)] 

我希望這有助於。

+0

看到我的#2回答爲做到這一點,試試好的,但 – 2013-03-10 07:38:41

+0

THX的提示,我會後您的解決方案 – yaens 2013-03-10 17:12:25