我想存储一组在构建时自动递增的整数:
int MajorVersion = 0;
int MinorVersion = 1;
int Revision = 92;
当我编译时,它会自动增加Revision。当我构建安装项目时,它会增加MinorVersion(我可以手动这样做)。MajorVersion只能手动递增。
然后我可以在菜单Help/About中显示一个版本号给用户:
Version: 0.1.92
如何实现这一目标?
这个问题不仅问如何有一个自动递增的版本号,还问如何在代码中使用它,这是一个比其他问题更完整的答案。
以下是来自MSDN的AssemblyInfo.cs上的引用:
You can specify all the values or you
can accept the default build number,
revision number, or both by using an
asterisk (). For example,
[assembly:AssemblyVersion("2.3.25.1")]
indicates 2 as the major version, 3 as
the minor version, 25 as the build
number, and 1 as the revision number.
A version number such as
[assembly:AssemblyVersion("1.2.")]
specifies 1 as the major version, 2 as
the minor version, and accepts the
default build and revision numbers. A
version number such as
[assembly:AssemblyVersion("1.2.15.*")]
specifies 1 as the major version, 2 as
the minor version, 15 as the build
number, and accepts the default
revision number. The default build
number increments daily. The default
revision number is random
这就是说,如果你放一个1.1。*进入组装信息,只有构建号会自动增加,它不会发生在每个构建后,而是每天。修订号会在每次构建时改变,但是是随机的,而不是以递增的方式。
这对于大多数用例来说可能已经足够了。如果这不是你想要的,你不得不写一个脚本,它将自动增加版本#在预构建步骤
*在版本(如“2.10.3.*”)-它是简单的,但数字太大
AutoBuildVersion -看起来很棒,但它不工作与我的VS2010。
@DrewChapin的脚本工作,但我不能在我的工作室为调试预构建事件和释放预构建事件设置不同的模式。
所以我修改了一下剧本…
命令:
"%CommonProgramFiles(x86)%\microsoft shared\TextTemplating\10.0\TextTransform.exe" -a !!$(ConfigurationName)!1 "$(ProjectDir)Properties\AssemblyInfo.tt"
和脚本(这适用于“调试”和“发布”配置):
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#
int incRevision = 1;
int incBuild = 1;
try { incRevision = Convert.ToInt32(this.Host.ResolveParameterValue("","","Debug"));} catch( Exception ) { incBuild=0; }
try { incBuild = Convert.ToInt32(this.Host.ResolveParameterValue("","","Release")); } catch( Exception ) { incRevision=0; }
try {
string currentDirectory = Path.GetDirectoryName(Host.TemplateFile);
string assemblyInfo = File.ReadAllText(Path.Combine(currentDirectory,"AssemblyInfo.cs"));
Regex pattern = new Regex("AssemblyVersion\\(\"\\d+\\.\\d+\\.(?<revision>\\d+)\\.(?<build>\\d+)\"\\)");
MatchCollection matches = pattern.Matches(assemblyInfo);
revision = Convert.ToInt32(matches[0].Groups["revision"].Value) + incRevision;
build = Convert.ToInt32(matches[0].Groups["build"].Value) + incBuild;
}
catch( Exception ) { }
#>
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("Game engine. Keys: F2 (Debug trace), F4 (Fullscreen), Shift+Arrows (Move view). ")]
[assembly: AssemblyProduct("Game engine")]
[assembly: AssemblyDescription("My engine for game")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCopyright("Copyright © Name 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 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. Only Windows
// assemblies support COM.
[assembly: ComVisible(false)]
// On Windows, the following GUID is for the ID of the typelib if this
// project is exposed to COM. On other platforms, it unique identifies the
// title storage container when deploying this assembly to the device.
[assembly: Guid("00000000-0000-0000-0000-000000000000")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("0.1.<#= this.revision #>.<#= this.build #>")]
[assembly: AssemblyFileVersion("0.1.<#= this.revision #>.<#= this.build #>")]
<#+
int revision = 0;
int build = 0;
#>
使用AssemblyInfo.cs
在App_Code中创建文件,并填写以下内容或使用谷歌获取其他属性/属性。
AssemblyInfo.cs
using System.Reflection;
[assembly: AssemblyDescription("Very useful stuff here.")]
[assembly: AssemblyCompany("companyname")]
[assembly: AssemblyCopyright("Copyright © me 2009")]
[assembly: AssemblyProduct("NeatProduct")]
[assembly: AssemblyVersion("1.1.*")]
AssemblyVersion是您真正需要的部分。
然后,如果你在一个网站上工作,在任何aspx页面或控件中,你可以在< page >标签中添加以下内容:
CompilerOptions="<folderpath>\App_Code\AssemblyInfo.cs"
(替换文件夹路径与适当的变量当然)。
我认为你不需要以任何方式为其他类添加编译器选项;App_Code中的所有文件在编译时都应该收到版本信息。
希望这能有所帮助。
如果您在项目中添加了一个AssemblyInfo类,并将AssemblyVersion属性修改为以星号结尾,例如:
[assembly: AssemblyVersion("2.10.*")]
Visual studio将根据这些规则为你增加最终的数字(谢谢galets,我完全错了!)
为了在代码中引用这个版本,以便可以将它显示给用户,可以使用反射。例如,
Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
DateTime buildDate = new DateTime(2000, 1, 1)
.AddDays(version.Build).AddSeconds(version.Revision * 2);
string displayableVersion = $"{version} ({buildDate})";
你应该知道三个重要的陷阱
从@ashes999:
同样值得注意的是,如果同时指定了AssemblyVersion和AssemblyFileVersion,则在.exe上不会看到此文件。
从@BrainSlugs83:
只将第4个数字设置为*可能会很糟糕,因为版本并不总是递增。
第三个数字是自2000年以来的天数,第四个数字是自午夜以来的秒数(除以2)[这不是随机的]。因此,如果您在某一天晚些时候构建解决方案,而在第二天早些时候构建解决方案,那么晚些时候构建的版本号将较早。我建议总是使用X.Y.*而不是x.y.z *,因为您的版本号总是会以这种方式增加。
新版本的Visual Studio会给出这样的错误:
(这个帖子开始于2009年)
指定的版本字符串包含与确定性不兼容的通配符。要么从版本字符串中删除通配符,要么禁用此编译的确定性。
看看这个SO答案,它解释了如何消除决定论(https://stackoverflow.com/a/58101474/1555612)
以下是来自MSDN的AssemblyInfo.cs上的引用:
You can specify all the values or you
can accept the default build number,
revision number, or both by using an
asterisk (). For example,
[assembly:AssemblyVersion("2.3.25.1")]
indicates 2 as the major version, 3 as
the minor version, 25 as the build
number, and 1 as the revision number.
A version number such as
[assembly:AssemblyVersion("1.2.")]
specifies 1 as the major version, 2 as
the minor version, and accepts the
default build and revision numbers. A
version number such as
[assembly:AssemblyVersion("1.2.15.*")]
specifies 1 as the major version, 2 as
the minor version, 15 as the build
number, and accepts the default
revision number. The default build
number increments daily. The default
revision number is random
这就是说,如果你放一个1.1。*进入组装信息,只有构建号会自动增加,它不会发生在每个构建后,而是每天。修订号会在每次构建时改变,但是是随机的,而不是以递增的方式。
这对于大多数用例来说可能已经足够了。如果这不是你想要的,你不得不写一个脚本,它将自动增加版本#在预构建步骤