C# 使用 MSI 安装版本设置 AssemblyInfo 版本号
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15222243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set AssemblyInfo Version numbers with MSI setup version
提问by santBart
I am using a setup project to publish my projects. I want the version of each project to be the same as the setup version.
我正在使用安装项目来发布我的项目。我希望每个项目的版本与安装版本相同。
I want to change my setup version property in Visual Studio and after building, for all project versions to be updated from this property, is this possible?
我想在 Visual Studio 中更改我的安装版本属性,并且在构建之后,对于要从此属性更新的所有项目版本,这可能吗?
采纳答案by Jeremy Thompson
Projects have Assembly & File version numbers: (not setup versions I edited your question accordingly)
项目具有程序集和文件版本号:(不是安装版本,我相应地编辑了您的问题)
Answer 1:
答案 1:
If you want to make the Setup projects version number set the Assembly & File version numbers you need to do it with a script/exe that gets triggered by the build.
如果您想让安装项目版本号设置程序集和文件版本号,您需要使用由构建触发的脚本/exe 来完成。
This article on How To Update Assembly Version Number Automaticallyshows half the solution...
这篇关于如何自动更新程序集版本号的文章显示了一半的解决方案......
From the research I did it is not possible to use the SetupVersion in a PreBuildEvent. There isn't a $SetupVersion command for it: http://msdn.microsoft.com/en-us/library/42x5kfw4(v=vs.80).aspx
根据我所做的研究,不可能在 PreBuildEvent 中使用 SetupVersion。它没有 $SetupVersion 命令:http: //msdn.microsoft.com/en-us/library/42x5kfw4(v=vs.80) .aspx
Having to change the PreBuildEvent each build as shown in this commentin the Code Project article using the -set:
command is not ideal.
必须使用命令更改每个构建的 PreBuildEvent,如代码项目文章中的此注释所示,-set:
并不理想。
The solution we need is a PreBuildEvent to call the AssemblyInfoUtil.exe and have it read the "ProductVersion" from the vdproj project file. And then update the Assembly version number(s).
我们需要的解决方案是调用 AssemblyInfoUtil.exe 并让它从 vdproj 项目文件中读取“ProductVersion”的 PreBuildEvent。然后更新程序集版本号。
I have modified the code from the article to show you how to read the product version from the Setup.vdproj and this is how it can be called from a PreBuildEvent:
我已经修改了文章中的代码,以向您展示如何从 Setup.vdproj 读取产品版本,这是从 PreBuildEvent 调用它的方式:
AssemblyInfoUtil.exe -setup:"C:\Program Files\MyProject1\Setup1\Setup1.vdproj" -ass:"C:\Program Files\MyProject1\AssemblyInfo.cs"
This is the modified code:
这是修改后的代码:
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;
}
}
}
Answer 2:
答案 2:
To my way of thinking a better way is to use a Shared Assembly Infoclass rather than individual AssemblyInfo class files.
在我看来,更好的方法是使用Shared Assembly Info类而不是单独的 AssemblyInfo 类文件。
To implement this, create a file in the solution folder named SharedAssemblyInfo.cs and then add a link in each project to SharedAssemblyInfo.cs. You can also move the linked SharedAssemblyInfo.cs into the Properties folder so that it sits side-by-side with the AssemblyInfo.cs that is specific to each project in the solution, as shown below.
要实现这一点,请在解决方案文件夹中创建一个名为 SharedAssemblyInfo.cs 的文件,然后在每个项目中添加一个指向 SharedAssemblyInfo.cs 的链接。您还可以将链接的 SharedAssemblyInfo.cs 移动到 Properties 文件夹中,使其与特定于解决方案中每个项目的 AssemblyInfo.cs 并排放置,如下所示。
Here is a sample SharedAssemblyInfo.cs file:
这是一个示例 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"
Here is a sample AssemblyInfo.cs file:
这是一个示例 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")]
So each time you want to change all projects Assembly info you can do it in one spot. I assume you would want to set the MSI Setup Version the same as the Assembly version number, one manual step.
因此,每次您想要更改所有项目组装信息时,您都可以在一个地方进行。我假设您希望将 MSI 安装版本设置为与程序集版本号相同,这是一个手动步骤。
Answer 3:
答案 3:
Consider switching to use MSBuildit has all these kinds of benefits but I'm not sure if you have the time to pick it up right now.
考虑改用MSBuild,它具有所有这些好处,但我不确定您现在是否有时间学习它。
Answer 4:
答案 4:
Assemblies can auto-increment their build numbers using the following asterisk syntax within AssemblyInfo.cs:
程序集可以在 AssemblyInfo.cs 中使用以下星号语法自动增加其内部版本号:
[assembly: AssemblyVersion("1.0.0.*")]
This is a good method because the point of tracking a build number is to be able to recognize different builds. Having a pre-build changing build numbers defeats this purpose as the build has not yet occurred.
这是一个很好的方法,因为跟踪内部版本号的目的是能够识别不同的内部版本。由于构建尚未发生,因此预构建更改构建编号会破坏此目的。
Answer 5:
答案 5:
The other CodeProjectanswer here assumes you want to update the ProductVersion, ProductCode, PackageCode
in the Setup MSI Project file. I didn't interpret your question that way and according to this thread there are problems:
pre-build event to change setup project's ProductVersion doesn't take effect until after the build
此处的另一个CodeProject答案假定您要更新ProductVersion, ProductCode, PackageCode
安装 MSI 项目文件中的 。我没有那样解释你的问题,根据这个线程存在问题:
预构建事件更改安装项目的 ProductVersion 直到构建之后才生效
Answer 6 (new):
答案 6(新):
There is a few TFS Build plugins to set "Assembly Info": https://marketplace.visualstudio.com/items?itemName=bleddynrichards.Assembly-Info-Taskhttps://marketplace.visualstudio.com/items?itemName=bool.update-assembly-infohttps://marketplace.visualstudio.com/items?itemName=ggarbuglia.setassemblyversion-task
有一些 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
回答by yaens
I don't know if this solves your problem perfectly but you could implement a common class with all the configmanagment informations like:
我不知道这是否能完美解决您的问题,但您可以使用所有配置管理信息实现一个通用类,例如:
public class VersionInfo{
public const string cProductVersion = "1.0.0"
//other version info
}
After you can update all your AssemblyInfo.cs with the new class:
在您可以使用新类更新所有 AssemblyInfo.cs 之后:
[assembly: AssemblyVersion(VersionInfo.cProductVersion)]
I hope this helps.
我希望这有帮助。