使用Visual Studio时可以自动增加文件生成版本吗?


358

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

如果我查找say的属性C:\Windows\notepad.exe,则“版本”选项卡将显示“文件版本:5.1.2600.2180”。我也想在我的dll版本中获得这些很酷的数字,而不是1.0.0.0版本,这让我们面对了它有些沉闷。

我尝试了一些方法,但是它似乎并不是开箱即用的功能,或者也许我只是在错误的地方(通常)。

我主要处理网络项目。

我看了两个:

  1. http://www.codeproject.com/KB/dotnet/Auto_Increment_Version.aspx
  2. http://www.codeproject.com/KB/dotnet/build_versioning.aspx

而且我不敢相信做某件事会付出太多努力是标准做法。

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


1
通配符似乎仅适用于AssemblyVersion,而不适用于VS 2005中的AssemblyFileVersion
dotnetcoder'

是否有任何解决方案可用于VS2005中的C ++项目?所有答案似乎都与.Net有关。相关问题。谢谢
Deanna

在.Net Core项目中,AssemblyVersion自动递增默认情况下不起作用。您需要将<Deterministic> False </ Deterministic>添加到csproj。请参阅自动版本的Visual Studio 2017年(.NET核心)
迈克尔Freidgeim

Answers:


434

在visual Studio 2008中,以下工作。

找到AssemblyInfo.cs文件并找到以下两行:

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

您可以尝试将其更改为:

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

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

但是,如果删除这些行的第二行,则只需:

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

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


2
这和其他任何东西一样好,并且可以在VS2005中使用。我希望像1.0.1.56一些有理数代替我得到1.0.3266.30135,但至少它增加(尽管一些随机数:d)
inspite

14
哦,我刚刚读过:它将自动在最后两个数字中填写日期(从某点开始的天数)和时间(从午夜开始的半秒)
尽管

20
很高兴需要删除AssemblyFileVersion属性以使其正常工作!
David Faivre

76
我意识到这是一个老问题,但想为其他寻求答案的人添加此评论。如果增加AssemblyVersion,则任何使用您dll的项目都需要重新编译。但是,如果保持AssemblyVersion不变,并单独增加AssemblyFileVersion,则可以交换新的dll,而无需重新编译正在使用的dll。所以问问自己,这仅仅是一个新版本,还是我要发布一个新版本?
onefootswill

27
@ DD59,“构建”是自2000年1月1日以来的天数;“修订”是从午夜开始的秒数除以 2(不是半秒,而是两秒的间隔)。看到这里:stackoverflow.com/a/3387167/11545
Cristian Diaconescu

154

打开AssemblyInfo.cs文件并进行更改

// 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")]

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

您可以在IDE中通过转到项目->属性->程序集信息来执行此操作

但是,这仅允许您自动递增程序集版本,并为您提供

程序集文件版本:此字段中不允许使用通配符(“ *”)

消息框(如果尝试在文件版本字段中放置*)。

因此,只需打开assemblyinfo.cs并手动进行即可。


是的,我刚刚遇到了“程序集文件版本:此字段中不允许使用通配符(“ *”)”,这是为您的方法赢得绿色勾号的原因:D
尽管时间为

3
这行得通:[assembly:AssemblyVersion(“ 1.0。*”)] // [assembly:AssemblyFileVersion(“ 1.0.0.0”)]
尽管时间为

4
在发布周期中,不希望更改AssemblyVersion编号。而是应更改AssemblyFileVersion。请参阅我关于此主题的博客文章:philippetruche.wordpress.com/2008/08/12/…另请参见Suzanne Cook关于何时更改数字的出色文章:blogs.msdn.com/b/suzcook/archive/2003/05/ 29 / 57148.aspx
Philippe

46
我会谨慎使用*,它将在2179年6月4日停止工作,当日期变为65536
Lloyd Powell


53

更改每个版本中版本号的另一种方法是使用MSBuild.Community.TasksVersion任务。只要下载安装了,安装它,然后适应下面的代码之后将其粘贴在你的文件:<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />.csproj

<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具有以下内容的:

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

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

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


2
这是我所见过的最好的方法,可以解决FileVersion结构使用16位整数的可怕事实。
Mike Post

1
我在使用Package Console安装到VS2012时遇到问题,因此建议在github.com/loresoft/msbuildtasks/downloads使用每晚下载的msi安装程序。从上面复制/粘贴作品。谢谢!
DaveO

被拒绝后,可以在这篇文章上进行编辑:“您可能还需要检查一下loresoft.com/projects/msbuildtasks/…,它可以改善前面描述的基本功能。”
radu florescu 2012年

1
对于使用TFS进行构建的人员而言,这不是可行的解决方案。最终,这会将未完成的编辑添加到VersionInfo.cs和version.txt文件中。对我来说,不希望每个构建都具有待处理的编辑。
JDennis 2014年

@JDennis请参阅此处以获取TFS版本控制技巧...
Christian

25

我想出了一个类似于Christians的解决方案,但不依赖于社区MSBuild任务,这不是我的选择,因为我不想为所有开发人员安装这些任务。

我正在生成代码并将其编译为Assembly,并希望自动增加版本号。但是,我不能使用VS 6.0。* AssemblyVersion技巧,因为它每天都会自动增加内部版本号,并且破坏了与使用较早内部版本号的程序集的兼容性。相反,我想要一个硬编码的AssemblyVersion,但是要一个自动递增的AssemblyFileVersion。我通过在AssemblyInfo.cs中指定AssemblyVersion并像这样在MSBuild中生成VersionInfo.cs来完成此任务,

  <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>

这将生成一个具有AssemblyFileVersion的Assembly属性的VersionInfo.cs文件,其中版本遵循带有生成日期的YY.MM.DD.TTTT的架构。您必须将此文件包含在您的项目中并使用它进行构建。


MSBuild是否支持变量?最好将其组合[System.DateTime]::Now成一个,否则,如果在午夜附近进行构建,则存在竞争条件可能会导致使用旧的内部版本号。
爱德华·布雷

您是否定义了这四个属性,而不是DateTime.ToString出于说明目的将它们组合在一起,还是有特定原因?
mafu

如果您BeforeBuild事件VS2017不火退房stackoverflow.com/questions/43921992/...
里斯-琼斯

此解决方案是此处所有答案中最合适的。但是,问题是,如果您第二次生成项目,则时间戳(或versioninfo.cs文件的内容)不会更新,这会产生不同的分钟。如果我关闭并重新加载项目,则时间戳会更新。这是MSBuild的错误吗?@Boog
卡里


12

要获取版本号,请尝试

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

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

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

另外,第三个数字是自2000年1月2日以来的天数,第四个数字是一天中总秒数的一半。因此,如果您在午夜编译,则应该为零。


12

有一个Visual Studio 扩展自动版本,该版本支持Visual Studio(2012、2013、2015)2017和2019。

屏幕截图 在此处输入图片说明

在此处输入图片说明


所以我已经卸载了它,我可以说更多...它修改了原始的csproj文件。我认为扩展很成问题。
Maxim

2
@Maxim Try最新版本,它应可在VS 2017上使用
Rady

优秀的工具。在vs2017中对我来说效果很好。文档可能会更清晰一些,但可以通过站点进行安装,然后通过Nuget安装MSBuild,将其应用于一个小型项目并进行构建。真好 @Boog的答案对我没有用,尽管他说了我正在努力实现的目标。
err1

8

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

Afaik在VS 2005中不起作用(但在VS 2003和VS 2008中起作用)。对于VS 2005,您可以使用以下命令:自动递增Visual Studio 2005版本的生成和编译时的修订号

但是请注意,不建议强命名程序集自动更改版本号。原因是,由于强命名的程序集引用始终是对特定程序集版本的引用,因此每次重新构建引用的程序集时,都必须更新对该程序集的所有引用。Microsoft本身仅在接口发生更改时才更改.NET Framework程序集的版本号。(注意:我仍在MSDN上搜索该链接,以了解该链接。)


我认为对于任何版本的VS,您都只能在“生成”或“修订”框中输入*。我刚刚使用VS 2005进行了尝试,效果很好。我不确定该代码项目文章的作者在谈论什么。
MusiGenesis

也许它带回来一个服务包,但我记得,它不使用工作,我用VS 2005的时候
德克福尔马尔

它不适用于2005,我将寻找一个Service Pack并进行报告。
尽管有

也许MusiGenesis已安装了一个附件,该附件可实现自动版本控制。
Dirk Vollmar

@divo:不,我有点恐惧。我只有Visual Studio 2005 Professional SP1。我从未见过*的问题,但我通常会手动增加。听起来像个奇怪的错误。
MusiGenesis

6

要将增量(DateTime)信息获取到AssemblyFileVersion属性中,该属性的优点是不会破坏任何依赖关系。


基于Boog的解决方案(对我来说不起作用,也许是因为VS2008吗?),可以结合使用预生成事件来生成文件,添加该文件(包括其版本属性),然后使用一种读取方式这些价值再次。那是..

预建活动:

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文件(“属性”子文件夹)包括到您的项目中

返回日期的代码(年数降至秒):

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),则可以使其更智能。我曾经成功完成过一次。


它运作完美。但是,此正则表达式%date:〜-4,4%。%date:〜-7,2 %% date:〜-10,2%。%time:〜0.2 %% time:〜3.2% 。%time:〜-5,2%“太复杂了。–
卡里

5

将版本号设置为“ 1.0。*”,它将自动在最后两个数字中填充日期(从某点开始的天数)和时间(从午夜开始的半秒)


嘿,如果我一开始就正确地阅读了这篇文章,我会省掉很多麻烦。thx
尽管有


4

Cake支持AssemblyInfo文件修补。有了蛋糕,您将有无限的方式来实现自动版本递增。

像C#编译器那样的递增版本的简单示例:

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”)。
  • FileVersion-是程序集文件版本。

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


3

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


2

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

它具有许多选项,其中包括将版本号与日期和时间关联的选项。

推荐的。


2

截至目前,对于我的应用,

string ver = Application.ProductVersion;

退货 ver = 1.0.3251.27860

值3251是自2000年1月1日以来的天数。我使用它在应用程序的初始屏幕上放置一个版本创建日期。与用户打交道时,我可以询问创建日期,该日期比一些长号更易于沟通。

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


您的电话号码快用完了。我将使用yyddd,它是从年初开始的2位数字年份和3位数字日期,最大值为365。至少您的程序可以编译到2065年。然后您将退休,并让其他人弄清楚他们想要如何处理它。由于您的程序当时仍在执行中!
AaA

2

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


2

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

这是一种实验,但我喜欢。受Jeff Atwood @ CodingHorror的启发(链接)。

产生的版本号变为1.2016.10709.11641(意味着2016-07-09 16:41),这允许

  • 可怜的人零填充(愚蠢的前导1s)
  • 版本号中嵌入了几乎人类可读的本地 DateTime
  • 仅保留主要版本,即可进行真正的重大更改。

在您的项目中添加一个新项目,选择“常规”->“文本模板”,将其命名为,CustomVersionNumber然后(在适用时)将AssemblyVersion和注释掉AssemblyFileVersionProperties/AssemblyInfo.cs

然后,在保存此文件或构建项目时,这将重新生成.cs位于创建.tt文件下的子项的文件。

<#@ 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}" #>")]

您不是每分钟都在编译程序,也不是每天进行多次部署,因此从技术上讲,时间部分不必要地占用了宝贵的信息,我将对主要未成年人使用1st和2nd,而对于日期yyddd则使用3rd数字(两位数的年份+从同年开始的ddd天开始),并在第4位保留递增的内部版本号。
AaA

2

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

  1. 下载申请书
  2. 将以下行添加到预构建事件命令行中

    C:\ temp \ IncrementFileVersion.exe $(SolutionDir)\ Properties \ AssemblyInfo.cs

  3. 建立项目

为简单起见,该应用程序仅在出现错误时才引发消息,为确保其正常工作,您需要在“汇编信息”中检查文件版本

注意:您将不得不在Visual Studio中重新加载“ Assembly Information”按钮的解决方案以填充字段,但是您的输出文件将具有更新的版本。

如有建议和要求,请给我发送电子邮件:telson_alva@yahoo.com


2

在Visual Studio 2019中

这对我来说还不够

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

在构建时会抛出此错误

指定的版本字符串不符合要求的格式

设置DeterministicFalsein 后,格式最终被接受project.csproj

<Deterministic>false</Deterministic>

编辑:

由于某种原因设置DeterministicFalse我的配置文件弄乱了,将其加载并保存在其他位置。

解决方法:

我设置了一个构建后事件来增加版本号:

构建后事件批处理脚本

这将调用一个名为powershell脚本autoincrement_version.ps1的路径,该脚本作为参数传递AssemblyInfo.cs

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

Poweshell脚本

它使用Regex自动递增修订号

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

1

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

    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中文件信息的任何部分(但必须使用“标准”目录结构)。




1

在这里回答也许为时已晚,但希望能解决某人的忙碌问题。

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


PS的唯一问题是反应速度慢,需要进行配置才能运行。我会选择一个小的可执行文件,一个tt4文件甚至是内联代码,我认为任何程序员都可以用一种方式编写该代码。
AaA

0

每次构建时,它都会自动递增最低有效位。

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


1
VS负责增加最后一个数字(通常是内部版本号)。其他所有内容(即之前的数字)由您决定,因为它们代表了应用程序的版本。
ОгњенШобајић

1
ОгњенШобајић:不太正确。微软的编号方案是major.minor.build.revision,例如1.0.4.7。如果将程序集版本设置为“ 1.0。*”,则VS将为您设置内部版本号和修订号。在这种情况下,构建每天将增加和修订将是自午夜起的秒数,除以2
西蒙Tewsi

0

对于使用Tortoise Subversion的任何人,您都可以将其中一个版本号与源代码的Subversion修订号绑定在一起。我觉得这很有用(审核员也真的很喜欢!)。您可以通过在预构建中调用WCREV实用程序并从模板生成AssemblyInfo.cs来实现。

如果您的模板名为AssemblyInfo.wcrev且位于常规AssemblyInfo.cs目录中,并且草龟位于默认的安装目录中,则您的Pre-Build命令如下所示(注意,在一行中全部为NB):

"C:\Program Files\TortoiseSVN\bin\SubWCRev.exe" "$(ProjectDir)." "$(ProjectDir)Properties\AssemblyInfo.wcrev"  "$(ProjectDir)Properties\AssemblyInfo.cs"

模板文件将包含wcrev令牌替换字符串:$ WCREV $
例如

[assembly: AssemblyFileVersion("1.0.0.$WCREV$")]

注意:
由于现在已生成AssemblyInfo.cs,因此不希望对其进行版本控制。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.