如何在.NET项目中使用发布日期作为程序集版本?

9
我知道汇编版本的格式是:
<major version>.<minor version>.<build number>.<revision>

有没有办法将版本号设置为当前日期?

例如,如果我今天编译构建,版本号应该像这样:

2016.02.11.xxxxx

当你将程序集版本设置为1.0.0.*时,xxxxx通常会被赋值。

我查阅了一些资料,但没有找到相关答案(甚至没有问题)。


2
只需使用 x.y.*,其中构建号是自2000年以来的天数,修订号是午夜后经过的秒数除以2。 - Hans Passant
4个回答

5

简单部分: 在项目属性 > 构建事件 中,添加一个“预构建事件命令行”,如下所示:

"D:\SomePath\MyAssemblyInfoPatcher.exe" "$(ProjectDir)Properties\AssemblyInfo.cs"

难点:您需要提供MyAssemblyInfoPatcher.exe,这是一个程序,它打开第一个参数指定的文件,并搜索其中的一行(忽略那里的值):

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

将该行替换为以下其中一种(或类似):
[assembly: AssemblyVersion("2016.11.05.2359")]
[assembly: AssemblyVersion("2016.1105.2359.1")]
[assembly: AssemblyVersion("8888.2016.1105.2359")]

程序从系统日期和时间中获取这些值,根据以下模式之一进行转换:

1. <yyyyMMddHHmmss>,即年月日时分秒

2. <yyyy-MM-dd HH:mm:ss>,即年-月-日 时:分:秒

并且重写文件。

yyyy.mm.dd.hhmm
yyyy.mmdd.hhmm.counter
arbitrary.yyyy.mmdd.hhmm

如果你硬编码你想要的模式,你的程序不需要配置。对于计数器(如果你选择了它),程序可以增加在文件中找到的值。计数器必须是单词(UInt16),这样当增加到65535时会回到0。如果你希望计数器每天重置一次,现在你需要存储一个参考日期,在一个侧面文件中或者可能在AssemblyInfo.cs的注释中。对于任意数字,你可以重用文件中的内容,或者硬编码替换。
时间问题:夏令时的开始和结束使得本地时间偶尔向前跳动一个小时(不是问题),并且向后跳动一个小时(总是很担心)。为了几乎保证没有重复的时间范围,你可以使用UTC或者也许是本地时间,忽略夏令时。许多Web服务器使用没有夏令时的本地时间,甚至是VS内置的可选自动基于日期的版本编号功能(它用a.b.*覆盖a.b.{自2000年1月1日00:00以来的天数}.{自2000年1月1日00:00以来的秒数除以2},因此它不可读)。
可能的简化:目标文件名始终为“AssemblyInfo.cs”,因此可在程序中指定并省略参数:“$(ProjectDir)Properties”。如果VS将当前目录设置为“D:\Users\myusername\Documents\Visual Studio 2010\Projects\solutionfolder\projectfolder\Properties”,就不需要参数。
一个程序可以通过System.Reflection.Assembly.GetExecutingAssembly().GetName().Version读取它的AssemblyVersion。文件:Properties 显示AssemblyFileVersion。如果没有指定AssemblyFileVersion,则默认为AssemblyVersion。

3

针对Visual Studio 2022,这里有一个新的解决方案,它需要修改csproj文件。

如何在Visual Studio 2022中使用日期/时间更改AssemblyInfo.cs AssemblyVersion并每天递增一个修订版本

从问题中复制:

以下是生成带有(年份、月份、日期、增量)版本的解决方案

此代码必须插入到*.csproj文件的</project>标签之前

<!-- Change AssemblyInfo.cs AssemblyVersion with date/time and increment revision daily by one in Visual Studio 2022 -->
<Target Name="AssemblyVersion" BeforeTargets="CoreCompile" DependsOnTargets="PrepareForBuild">
    <PropertyGroup>
        <!-- Define Constants -->
        <AssemblyInfo>Properties\AssemblyInfo.cs</AssemblyInfo>
        <AssemblyInfoContent>$([System.IO.File]::ReadAllText($(AssemblyInfo)))</AssemblyInfoContent>
        <VersionRegex>(\[\s*assembly\s*:\s*AssemblyVersion\(\s*"(\d+)\.(\d+)\.(\d+)(\.)(\d+)("\)\s*\]))</VersionRegex>
        <BuildAndRevisionRegex>(\d+\.\d+")</BuildAndRevisionRegex>

        <!-- Parse Build and Revision from AssemblyInfo-->
        <AssemblyVersion>$([System.Text.RegularExpressions.Regex]::Match('$(AssemblyInfoContent)', '$(VersionRegex)'))</AssemblyVersion>
        <BuildAndRevision>$([System.Text.RegularExpressions.Regex]::Match('$(AssemblyVersion)', '$(BuildAndRevisionRegex)'))</BuildAndRevision>
        <BuildAndRevision>$(BuildAndRevision.Remove($(BuildAndRevision.LastIndexOf('"')), 1))</BuildAndRevision>
        
        <!-- Generate Build and Revision from AssemblyVersion -->
        <Build>$(BuildAndRevision.SubString(0, $(BuildAndRevision.LastIndexOf('.'))))</Build>
        <Revision>$(BuildAndRevision.SubString($([MSBuild]::Add($(BuildAndRevision.LastIndexOf('.')), 1))))</Revision>
        
        <!-- Increment Revision by one if Build equal Current Day otherwise start from one as new Day Build-->
        <Revision Condition ="$([System.DateTime]::Now.Day) == $(Build)">$([MSBuild]::Add($(Revision), 1))</Revision>
        <Revision Condition ="$([System.DateTime]::Now.Day) != $(Build)">1</Revision>

        <!-- New AssemblyVersion Block -->
        <AssemblyVersion>[assembly: AssemblyVersion("$([System.DateTime]::Now.ToString("yyyy.M.d.$(Revision)"))")]</AssemblyVersion>
    </PropertyGroup>

    <!-- Write New AssemblyVersion Block to AssemblyInfo.cs file -->
    <WriteLinesToFile File="$(AssemblyInfo)" Lines="$([System.Text.RegularExpressions.Regex]::Replace($(AssemblyInfoContent), $(VersionRegex), $(AssemblyVersion)))" Overwrite="true" />
</Target>

生成的结果如下:
  1. 每天一个库/项目将从(年,月,日,每日日增量)开始。

Incremental daily

  1. 接下来的一天再次增加: Next Day increment from one again

2

这可以通过MSBUILD完成。这里有一个很好的描述。 你不需要构建服务器。你可以在项目的BeforeBuild目标中调用自定义的MSBUILD目标。为此,使用编辑器打开csproj文件并定位文件末尾的此部分:

<!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->

您提供的链接似乎已经失效了(?至少对我来说是今天)。但是以下链接在我的.Net Core项目中可以使用:https://scottdorman.blog/2018/08/20/net-core-project-versioning/。 - Stefan Wuebbe

1
using System;
using System.IO;
using System.Linq;

namespace MyAssemblyInfoPatcher
{
    internal class Program
    {
        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                string path = args[0].ToString();
                Console.WriteLine(string.Format("Current App version is set to: {0}", path));
                string now_date = DateTime.Now.ToString("yyyy.MM.dd.HHmm");
                if (File.Exists(path))
                {
                    string _AssemblyVersion = string.Empty;
                    string _AssemblyFileVersion = string.Empty;

                    var lines = File.ReadLines(string.Format(path));
                    for (int i = 0; i < lines.Count(); i++)
                    {
                        if (lines.ElementAt(i).ToString().StartsWith("[assembly: AssemblyVersion"))
                        {
                            _AssemblyVersion = lines.ElementAt(i).ToString();
                        }
                        else if (lines.ElementAt(i).ToString().StartsWith("[assembly: AssemblyFileVersion"))
                        {
                            _AssemblyFileVersion = lines.ElementAt(i).ToString();
                        }
                    }

                    string _replace_assembly = File.ReadAllText(path);

                    if (_AssemblyVersion != string.Empty)
                    {
                        _replace_assembly = _replace_assembly.Replace(_AssemblyVersion, string.Format("[assembly: AssemblyVersion(\"{0}\")]", now_date));
                    }
                    if (_AssemblyFileVersion != string.Empty)
                    {
                        _replace_assembly = _replace_assembly.Replace(_AssemblyFileVersion, string.Format("[assembly: AssemblyFileVersion(\"{0}\")]", now_date));
                    }

                    File.WriteAllText(path, _replace_assembly);
                }
            }   
        }
    }
}

在程序代码上方,您可以创建一个控制台应用程序,并在项目属性>构建事件中添加一个“预构建事件命令行”,如下所示: “D:\ SomePath \ MyAssemblyInfoPatcher.exe” “$(ProjectDir)Properties \ AssemblyInfo.cs”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接