关于c#:使用Visual Studio时,我可以自动增加文件构建版本吗?

Can I automatically increment the file build version when using Visual Studio?

我只是想知道如何自动增加构建(和版本?)使用Visual Studio(2005)创建的文件。

如果我查找say C:\Windows
otepad.exe
的属性,版本选项卡会给出"文件版本:5.1.2600.2180"。我也希望在我的dll版本中得到这些很酷的数字,而不是1.0.0.0版本,让我们面对它有点迟钝。

我尝试了一些东西,但它似乎没有开箱即用的功能,或者我只是在找错地方(像往常一样)。

我主要从事网络项目……

我看了两个:

  • http://www.codeproject.com/kb/dotnet/auto_increment_version.aspx
  • http://www.codeproject.com/kb/dotnet/build_versioning.aspx
  • 我真不敢相信这么多的努力是标准的做法。

    编辑:据我所知,它在VS2005中不起作用(http://www.codeproject.com/kb/dotnet/autoincrementversion.aspx)


    在Visual Studio 2008中,可以执行以下操作。

    查找assemblyinfo.cs文件并查找这两行:

    1
    2
    [assembly: AssemblyVersion("1.0.0.0")]
    [assembly: AssemblyFileVersion("1.0.0.0")]

    您可以尝试将此更改为:

    1
    2
    [assembly: AssemblyVersion("1.0.*")]
    [assembly: AssemblyFileVersion("1.0.*")]

    但这不会给你期望的结果,你最终会得到1.0.*的产品版本和1.0.0.0的文件版本。不是你想要的!

    但是,如果删除这些行中的第二行并只具有:

    1
    [assembly: AssemblyVersion("1.0.*")]

    然后编译器将文件版本设置为等于产品版本,您将得到同步的自动递增产品和文件版本的所需结果。例如1.0.3266.92689


    打开assemblyinfo.cs文件并更改

    1
    2
    3
    4
    5
    // You can specify all the values or you can default the Build and Revision Numbers
    // by using the '*' as shown below:
    // [assembly: AssemblyVersion("1.0.*")]
    [assembly: AssemblyVersion("1.0.0.0")]
    [assembly: AssemblyFileVersion("1.0.0.0")]

    1
    2
    [assembly: AssemblyVersion("1.0.*")]
    //[assembly: AssemblyFileVersion("1.0.0.0")]

    您可以在IDE中通过转到project->properties->assembly information来完成此操作。

    但是,这只允许您自动增加程序集版本,并将为您提供

    Assembly File Version: A wildcard ("*") is not allowed in this field

    如果尝试在"文件版本"字段中放置一个*,则显示消息框。

    所以只需打开assemblyinfo.cs并手动执行即可。


    更改每个生成中版本号的另一个选项是使用msbuild.community.tasks的版本任务。只需下载他们的安装程序,安装它,然后修改以下代码并将其粘贴到您的.csproj文件中的之后:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
    <Target Name="BeforeBuild">
        <Version VersionFile="Properties\version.txt" Major="1" Minor="0" BuildType="Automatic" StartDate="12/31/2009" RevisionType="BuildIncrement">
          <Output TaskParameter="Major" PropertyName="Major" />
          <Output TaskParameter="Minor" PropertyName="Minor" />
          <Output TaskParameter="Build" PropertyName="Build" />
          <Output TaskParameter="Revision" PropertyName="Revision" />
        </Version>
        <AssemblyInfo CodeLanguage="CS"
                      OutputFile="Properties\VersionInfo.cs"
                      AssemblyVersion="$(Major).$(Minor)"
                      AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" />
    </Target>

    注意:根据您的区域设置调整StartDate属性。它当前不使用固定区域性。

    对于2010年1月14日的第三次构建,这将创建一个包含以下内容的VersionInfo.cs

    1
    2
    [assembly: AssemblyVersion("1.0")]
    [assembly: AssemblyFileVersion("1.0.14.2")]

    然后,必须将该文件添加到项目中(通过添加现有项),并且必须从AssemblyInfo.cs中删除AssemblyVersionAssemblyFileVersion行。

    $(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.chm和版本属性中描述了更改版本组件的不同算法。


    我提出了一个类似于基督教徒的解决方案,但不依赖于社区的msbuild任务,这对我来说不是一个选项,因为我不想为所有开发人员安装这些任务。

    我正在生成代码并编译到程序集,希望自动增加版本号。但是,我不能使用vs 6.0.*assemblyversion技巧,因为它每天自动增加内部版本号,并破坏与使用旧内部版本号的程序集的兼容性。相反,我希望有一个硬编码的assemblyversion,但要有一个自动递增的assemblyfileversion。我通过在assemblyinfo.cs中指定assemblyversion并在msbuild中生成versioninfo.cs来完成此操作,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
      <PropertyGroup>
        <Year>$([System.DateTime]::Now.ToString("yy"))</Year>
        <Month>$([System.DateTime]::Now.ToString("MM"))</Month>
        <Date>$([System.DateTime]::Now.ToString("dd"))</Date>
        <Time>$([System.DateTime]::Now.ToString("HHmm"))</Time>
        <AssemblyFileVersionAttribute>[assembly:System.Reflection.AssemblyFileVersion("$(Year).$(Month).$(Date).$(Time)")]</AssemblyFileVersionAttribute>
      </PropertyGroup>
      <Target Name="BeforeBuild">
        <WriteLinesToFile File="Properties\VersionInfo.cs" Lines="$(AssemblyFileVersionAttribute)" Overwrite="true">
        </WriteLinesToFile>
      </Target>

    这将为assembly file version生成一个带有assembly属性的versioninfo.cs文件,其中版本遵循带有生成日期的yy.mm.dd.tttt模式。您必须将此文件包含在项目中并使用它进行生成。


    安装生成版本增量加载项。它给了你比*选项更多的控制权。


    要获取版本号,请尝试

    1
    2
    3
     System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
     System.Reflection.AssemblyName assemblyName = assembly.GetName();
     Version version = assemblyName.Version;

    要设置版本号,请创建/编辑assemblyinfo.cs

    1
    2
     [assembly: AssemblyVersion("1.0.*")]
     [assembly: AssemblyFileVersion("1.0.*")]

    另请注意,第三个数字是自2000年2月1日起的天数,第四个数字是当天总秒数的一半。所以,如果您在午夜编译,它应该是零。


    有一个支持Visual Studio 2012、2013、2015和2017的Visual Studio扩展自动版本。

    屏幕快照enter image description here

    氧化镁


    在assemblyinfo中的版本号或其他文章中描述的项目属性下设置*不适用于所有版本的Visual Studio/.NET。

    Afaik在2005年和2008年都不起作用(但在2003年和2008年)。对于VS2005,您可以使用以下命令:在编译时自动增加Visual Studio 2005版本的内部版本号和修订号。

    但请注意,对于强名称程序集,不建议自动更改版本号。原因是每次重建引用的程序集时,必须更新对此类程序集的所有引用,因为强名称程序集引用始终是对特定程序集版本的引用。只有在接口发生更改时,Microsoft自己才更改.NET框架程序集的版本号。(注意:我还在搜索我读到的msdn中的链接。)


    将递增(日期时间)信息获取到assemblyfileversion属性中,该属性具有不破坏任何依赖项的优势。

    基于Boog的解决方案(对我来说不起作用,可能是因为VS2008?),您可以使用生成文件的预生成事件的组合,添加该文件(包括其版本属性),然后使用再次读取这些值的方法。那是……

    预生成事件:

    1
    echo [assembly:System.Reflection.AssemblyFileVersion("%date:~-4,4%.%date:~-7,2%%date:~-10,2%.%time:~0,2%%time:~3,2%.%time:~-5,2%")] > $(ProjectDir)Properties\VersionInfo.cs

    将生成的versioninfo.cs文件(属性子文件夹)包含到项目中

    获取日期的代码(从年到秒):

    1
    2
    3
    4
    var version = assembly.GetName().Version;
    var fileVersionString = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion;
    Version fileVersion = new Version(fileVersionString);
    var buildDateTime = new DateTime(fileVersion.Major, fileVersion.Minor/100, fileVersion.Minor%100, fileVersion.Build/100, fileVersion.Build%100, fileVersion.Revision);

    不太舒服……此外,我不知道它是否会创建大量的强制重建(因为文件总是会更改)。

    例如,如果只每隔几分钟/小时更新versioninfo.cs文件(通过使用临时文件,然后在检测到足够大的更改时复制/覆盖真正的versioninfo.cs),则可以使其更智能。这一次我做得相当成功。


    将版本号设置为"1.0.*",它将自动在最后两个数字中填入日期(从某个时间点算起以天为单位)和时间(从午夜算起以半秒为单位)。


    cake支持assemblyinfo文件修补。有了蛋糕,您就有了无限的方法来实现自动版本递增。

    像C编译器这样的递增版本的简单示例如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Setup(() =>
    {
        // Executed BEFORE the first task.
        var datetimeNow = DateTime.Now;
        var daysPart = (datetimeNow - new DateTime(2000, 1, 1)).Days;
        var secondsPart = (long)datetimeNow.TimeOfDay.TotalSeconds/2;
        var assemblyInfo = new AssemblyInfoSettings
        {
            Version ="3.0.0.0",
            FileVersion = string.Format("3.0.{0}.{1}", daysPart, secondsPart)
        };
        CreateAssemblyInfo("MyProject/Properties/AssemblyInfo.cs", assemblyInfo);
    });

    在这里:

    • 版本-是程序集版本。最佳做法是锁定主要版本号,并保留零(如"1.0.0.0")。
    • file version-是程序集文件版本。

    请注意,您不仅可以修补版本,还可以修补所有其他必需的信息。


    它在"发布"下的项目属性中

    http://screencast.com/t/Vj7rhqJO
    (~http://screencast.com/t/vj7rhqjo)


    转到"项目属性",然后转到"程序集信息",然后转到"程序集版本",并在"最后一个"或"第二个到最后一个"框中放置一个*(不能自动增加主要或次要组件)。


    使用msbuild社区任务(http://msbuild tasks.tigris.org/)项目中的assemblyinfo任务,并将其集成到.csproj/.vbproj文件中。

    它有许多选项,包括一个将版本号与日期和时间绑定的选项。

    推荐。


    目前为止,对于我的申请,

    1
    string ver = Application.ProductVersion;

    返回ver = 1.0.3251.27860

    值3251是自2000年1月1日起的天数。我用它在应用程序的初始屏幕上显示一个版本创建日期。当与用户打交道时,我可以问创建日期,它比一些长数字更容易沟通。

    (我是一个支持一家小公司的单人部门。这种方法可能不适用于您。)


    如何获取版本{major}.{year}.1{date}.1{time}

    这是一种实验,但我喜欢。灵感来自Jeff Atwood@coding恐怖(link)。

    生成的版本号变为1.2016.10709.11641(意思是2016-07-09 16:41),允许

    • 可怜的人零填充(与愚蠢的领导1s)
    • 嵌入到版本号中的几乎人类可读的本地日期时间
    • 将主要版本单独用于真正重大的突破性更改。

    在项目中添加一个新项目,选择General(常规)->Text template(文本模板),将其命名为CustomVersionNumber,并在Properties/AssemblyInfo.cs中注释AssemblyVersionAssemblyFileVersion

    然后,在保存此文件或构建项目时,将重新生成一个.cs文件,该文件作为创建的.tt文件下的子项。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <#@ template language="C#" #>
    <#@ assembly name="System.Core" #>
    <#@ import namespace="System.Linq" #>

    //
    // This code was generated by a tool. Any changes made manually will be lost
    // the next time this code is regenerated.
    //

    using System.Reflection;

    <#
        var date = DateTime.Now;
        int major = 1;
        int minor = date.Year;
        int build = 10000 + int.Parse(date.ToString("MMdd"));
        int revision = 10000 + int.Parse(date.ToString("HHmm"));
    #>

    [assembly: AssemblyVersion("<#= $"{major}.{minor}.{build}.{revision}" #>")]
    [assembly: AssemblyFileVersion("<#= $"{major}.{minor}.{build}.{revision}" #>")]


    更改assemblyinfo在VS2012中有效。奇怪的是,在Visual Studio中没有对此的更多支持,您会认为这是构建/发布过程的基本部分。


    也许现在回答这个问题已经太迟了,但希望能解决某人的难题。

    使用PowerShell脚本自动更改所有项目的程序集版本。本文将解决您的许多问题。


    也许,对于这个任务,您可以使用如下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
        private bool IncreaseFileVersionBuild()
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                try
                {
                    var fi = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory).Parent.Parent.GetDirectories("Properties")[0].GetFiles("AssemblyInfo.cs")[0];
                    var ve = System.Diagnostics.FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
                    string ol = ve.FileMajorPart.ToString() +"." + ve.FileMinorPart.ToString() +"." + ve.FileBuildPart.ToString() +"." + ve.FilePrivatePart.ToString();
                    string ne = ve.FileMajorPart.ToString() +"." + ve.FileMinorPart.ToString() +"." + (ve.FileBuildPart + 1).ToString() +"." + ve.FilePrivatePart.ToString();
                    System.IO.File.WriteAllText(fi.FullName, System.IO.File.ReadAllText(fi.FullName).Replace("[assembly: AssemblyFileVersion("" + ol +"")]","[assembly: AssemblyFileVersion("" + ne +"")]"));
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            return false;
        }

    从窗体加载调用它。
    使用此代码,您可以更新assemblyinfo.cs中文件信息的任何部分(但必须使用"标准"目录结构)。


    汇编信息工具。免费。开源。


    我使用这种方法https://stackoverflow.com/a/827209/3975786,将t4模板放在"解决方案项"中,并在每个项目中使用"添加为链接"。


    在Visual Studio 2019中

    对我来说还不够

    1
    [assembly: AssemblyVersion("1.0.*")]

    当构建它时,它抛出了这个错误

    The specified version string does not conform to the required format

    号解决方案

    我在project.csproj中把Deterministic设为False后,格式终于被接受了。

    1
    <Deterministic>false</Deterministic>

    编辑:

    出于某种原因,将Deterministic设置为False会使我的配置文件加载混乱,并将其保存到不同的位置。

    解决方法:

    我设置了一个生成后事件以增加修订号:

    生成后事件批处理脚本

    这调用一个名为autoincrement_version.ps1的PowerShell脚本作为参数传递AssemblyInfo.cs的路径。

    1
    2
    3
    if $(ConfigurationName) == Release (
    PowerShell -ExecutionPolicy RemoteSigned $(ProjectDir)autoincrement_version.ps1 '$(ProjectDir)My Project\AssemblyInfo.cs'
    )

    。鲍威尔剧本

    它使用regex自动增加版本号

    1
    2
    3
    4
    5
    6
    param( [string]$file );
      $regex_revision = '(?<=Version\("(?:\d+\.)+)(\d+)(?="\))'
      $found = (Get-Content $file) | Select-String -Pattern $regex_revision
      $revision = $found.matches[0].value
      $new_revision = [int]$revision + 1
      (Get-Content $file) -replace $regex_revision, $new_revision | Set-Content $file -Encoding UTF8

    我已经创建了一个自动增加文件版本的应用程序。

  • 下载应用程序
  • 将以下行添加到预生成事件命令行

    C: empincrementfileversion.exe$(solutiondir)propertiesassemblyinfo.cs

  • 建立项目

  • 要保持简单,应用程序只会在出现错误时抛出消息,要确认它工作正常,您需要检查"程序集信息"中的文件版本。

    注意:您必须在Visual Studio中重新加载解决方案以获取"程序集信息"按钮来填充字段,但是输出文件将具有更新的版本。

    有关建议和请求,请发电子邮件至[email protected]


    每次我构建它时,它都会自动增加最低有效数字。

    我不知道如何更新其他人,但你至少应该已经看到了…