【问题标题】:SVN Revision Version in .NET Assembly w/ out CC.NET.NET 程序集中的 SVN 修订版,不带 CC.NET
【发布时间】:2010-09-05 22:41:45
【问题描述】:

有没有办法在 .NET 程序集的版本字符串中包含 SVN 存储库修订号?类似于 Major.Minor.SVNRev

我看到有人提到使用 CC.NET 之类的东西(虽然实际上是在 ASP.NET 上),但有没有任何方法可以在没有任何额外软件的情况下做到这一点?在使用构建批处理脚本之前,我在 C/C++ 中做过类似的事情,但是通过读取版本号来完成,然后让脚本每次都写出一个名为“ver.h”的文件,效果如下:

#define MAJORVER 4
#define MINORVER 23
#define SOURCEVER 965

然后我们将使用这些定义来生成版本字符串。

.NET 可以实现这样的事情吗?

【问题讨论】:

  • Stackoverflow 在页脚显示修订号,也许 Jeff 可以告诉我们他是如何做到的。
  • 这个非常棒——日期和svn版本号fatlemon.co.uk/2011/11/…
  • 看我的回答 - 有一个 github 项目可以做到这一点
  • 上面的链接可能无法正确加载。 github url在我下面的答案中。 - 对于使用日期和 svn rev number 的解决方案。

标签: .net svn versioning


【解决方案1】:

这里是自动更新程序集中修订信息的 C# 示例。它基于 Will Dean 的回答,不是很详细。

例子:

  1. 将 AssemblyInfo.cs 复制到项目中的 AssemblyInfoTemplate.cs 文件夹属性
  2. 将 AssemblyInfoTemplate.cs 的 Build Action 更改为 None
  3. 将带有 AssemblyFileVersion 的行修改为:

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

  4. 考虑添加:

    [assembly: AssemblyInformationalVersion("Build date: $WCNOW=%Y-%m-%d %H:%M:%S$; Revision date: $WCDATE=%Y-%m-%d %H:%M:%S$; Revision(s) in working copy: $WCRANGE$$WCMODS?; WARNING working copy had uncommitted modifications:$.")],

    这将提供有关构建程序集的源的修订状态的详细信息。

  5. 将以下 Pre-build 事件添加到项目文件属性中:

    subwcrev "$(SolutionDir)." "$(ProjectDir)Properties\AssemblyInfoTemplate.cs" "$(ProjectDir)Properties\AssemblyInfo.cs" -f

  6. 考虑将 AssemblyInfo.cs 添加到 svn 忽略列表中。替换的修订号和日期将修改文件,这会导致微不足道的更改和修订,并且 $WCMODS$ 将评估为真。当然,AssemblyInfo.cs 必须包含在项目中。

针对 Wim Coenen 的反对意见,我注意到,与 Darryl 的建议相反,AssemblyFileVersion 也支持 2^16 以上的数字。构建将完成,但实际程序集中的属性 File Version 将为 AssemblyFileVersion 模 65536。因此,1.0.0.65536 以及 1.0.0.131072 将产生 1.0.0.0 等。在此示例中, AssemblyInformationalVersion 属性中始终存在真实的修订号。如果您认为这是一个重要问题,您可以省略第 3 步。

编辑:使用此解决方案一段时间后的一些附加信息。

  1. 它现在使用 AssemblyInfo.cst 而不是 AssemblyInfoTemplate.cs,因为它会自动具有 Build Action 选项 None,它不会使您的错误列表变得混乱,但是您'将松动语法高亮。
  2. 我在 AssemblyInfo.cst 文件中添加了两个测试:

    #if(!DEBUG)    
        $WCMODS?#error Working copy has uncommitted modifications, please commit all modifications before creating a release build.:$ 
    #endif 
    #if(!DEBUG)       
        $WCMIXED?#error Working copy has multiple revisions, please update to the latest revision before creating a release build.:$ 
    #endif
    

    使用此方法,您通常必须在提交之后和成功发布构建之前执行完整的 SVN 更新。否则,$WCMIXED 将为真。这似乎是由于提交的文件在提交后重新在头部修订,但其他文件不是。

  3. 我一直怀疑 subwcrev 的第一个参数“$(SolutionDir)”,它设置了检查 svn 版本信息的范围,是否总是按预期工作。也许,它应该是 $(ProjectDir),如果您对每个单独的程序集都处于一致的修订版感到满意。

加法 回答@tommylux 的评论。

SubWcRev 可用于项目中的任何文件。如果你想在网页中显示修订信息,你可以使用这个 VersionInfo 模板:

public class VersionInfo
{       
    public const int RevisionNumber = $WCREV$;
    public const string BuildDate = "$WCNOW=%Y-%m-%d %H:%M:%S$";
    public const string RevisionDate = "$WCDATE=%Y-%m-%d %H:%M:%S$";
    public const string RevisionsInWorkingCopy = "$WCRANGE$";
    public const bool UncommitedModification = $WCMODS?true:false$;
}

添加一个与 AssemblyInfo.cst 类似的预构建事件,您将可以轻松访问所有相关的 SubVersion 信息。

【讨论】:

  • 同意,这是正确的答案,而不仅仅是指向可以使用的工具的信息的链接。
  • 您能否详细说明第二部分。我不完全理解它。您将 AssemblyInfo.cs 重命名为 AssemblyInfo.cst?要么?模板发生了什么?您在哪里添加了这些新测试?在文件的哪一部分?顺便说一句,答案很好!
  • @100r,我更正了我写错的文件名。我希望这能解决你的困惑。如果没有,请告诉我。
  • 这看起来很不错,但是您将如何在 ASP 页中打印它呢?即:
  • 看来我已经弄清楚了你的课堂问题。我想这是因为我不知道 cst 文件是如何工作的。当您将 Public Class VersionInfo 放入 cst 时,在构建时,这将填充 cs 文件,然后它可以在项目中使用来自源代码控制的翻译版本信息。再次感谢。
【解决方案2】:

另一个答案提到,由于数字大小的限制,SVN 修订号可能不是一个好主意。

以下链接不仅提供了 SNV 修订号,还提供了日期版本信息模板。

将它添加到 .NET 项目很简单 - 需要做的工作很少。

这是一个解决这个问题的 github 项目 https://github.com/AndrewFreemantle/When-The-Version/downloads

以下网址可能会加载缓慢,但会逐步说明如何完成这项工作(简单而简短的 3 或 4 步)

http://www.fatlemon.co.uk/2011/11/wtv-automatic-date-based-version-numbering-for-net-with-whentheversion/

【讨论】:

  • 这个解决方案快速有效
【解决方案3】:

您可以使用可以在所有项目中引用的共享程序集版本文件。

UppercuT 这样做 - http://ferventcoder.com/archive/2009/05/21/uppercut---automated-builds---versionbuilder.aspx

这将使您了解如何在程序集中获取版本。

【讨论】:

    【解决方案4】:

    这是可能的,但您不应该这样做:程序集版本字符串的组件被限制为 16 位数字(最大 65535)。 Subversion 版本号很容易变得比这个大,所以在某些时候编译器会突然抱怨。

    【讨论】:

    • 好点。每天提交 20 次,这将持续 8 年。 100 次提交将持续不到 2 年。对于小型项目可能没问题。当然不适合大的。
    • @Tim,仅当项目成员每周 7 天全职工作时 :-) 假设每周工作 5 天,估计分别为 13 年和 2.6 年。对于前一种情况,差异可能很大。
    • 另外,如果它破坏了与以前版本的兼容性,您应该只更改程序集版本 - 您不应该将构建版本信息放入程序集版本。构建版本信息可以而且应该放入 AssemblyFileVersion,它支持 32 位数字。见stackoverflow.com/questions/64602
    • -1,这不是一个很好的理由。对于大多数产品来说,65536 次提交并不是一个实际限制。即使对于确实超过该数字的产品,major-minor-rev 也应该提供足够的上下文来“解开”正确值的修订(如果您的应用程序的每个修订版肯定不会有 64k 次提交)正在明智地进行版本控制)。
    • @soupdog:您对“展开”修订的建议是我认为自己的好建议。不过,这会使事情变得有些复杂,因为您需要选择一个偏移量以从修订版中减去,并记住在每次major.minor 更改时检查是否需要更新偏移量。维护是另外一件事。当您拥有像我们这样具有数万次修订的存储库时,认知负荷是一个问题。
    【解决方案5】:

    阅读/浏览这些文档:

    Accessing the Subversion repository from .NET using DotSVN

    How to: Write a Task

    Insert SVN version and Build number in your C# AssemblyInfo file

    Compiling Apps With Custom Tasks For The Microsoft Build Engine

    第三个参考资料中提到的 MSBuildCommunityTasks svnversion 无法在 Mac 10.5.6 和 VS2008 C# 项目中使用 svn 在 Parallels 托管 Vista 中构建(即跨操作系统)。

    编写您自己的任务以使用 DotSVN 从存储库中检索修订:

    using System;
    using Microsoft.Build.Framework;
    using Microsoft.Build.Utilities;
    using DotSVN.Common;
    using DotSVN.Common.Entities;
    using DotSVN.Common.Util;
    using DotSVN.Server.RepositoryAccess;
    
    namespace GetSVNVersion
    {
        public class GetRevision : Task
        {
            [Required]
            public string Repository { get; set; }
            [Output]
            public string Revision { get; set; }
    
            public override bool Execute()
            {
                ISVNRepository repo;
                bool connected = true;
                try
                {
                    repo = SVNRepositoryFactory.Create(new SVNURL(Repository));
                    repo.OpenRepository();
                    Revision = repo.GetLatestRevision().ToString();
                    Log.LogCommandLine(Repository + " is revision " + Revision);
                    repo.CloseRepository();
                }
                catch(Exception e)
                {
                    Log.LogError("Error retrieving revision number for " + Repository + ": " + e.Message);
                    connected = false;
                }
                return connected;
            }
        }
    }
    

    这种方式允许存储库路径为“file:///Y:/repo”,其中 Y: 是映射到 Vista 中的 Mac 目录。

    【讨论】:

    • 不幸的是 dotSVN 不再维护,其中一个被遗漏的东西是 http 上的存储库。
    【解决方案6】:

    如果您想更新项目 AssemblyInfo.cs 中的版本号,您可能会对这篇文章感兴趣:

    CodeProject: Use Subversion Revision numbers in your Visual Studio Projects

    如果您启用 SVN 关键字,那么每次您签入项目时,Subversion 都会扫描您的文件以查找某些“关键字”并用一些信息替换这些关键字。

    例如,在我的源文件顶部,我会创建一个包含以下关键字的标题:

    '$作者:$
    '$Id:$
    '$修订:$

    当我将此文件签入 Subversion 时,这些关键字将替换为以下内容:

    '$作者:paulbetteridge $
    '$Id: myfile.vb 145 2008-07-16 15:24:29Z paulbetteridge $
    '$ Rev: 145 $

    【讨论】:

    • 来自那篇文章:“使用 $Rev$ 关键字的限制是它只为您提供文件的修订版而不是整个项目,因此使用 $rev$ 关键字不能作为我的一部分软件版本控制。”所以你必须在每个修订版上编辑/提交 assembly.cs 以保持更新?
    【解决方案7】:

    svn info,告诉你你正在使用的版本,你可以在 VS 中对你的项目进行“预构建”事件,通过运行 svn info 并使用自制的命令行应用程序解析其结果来生成 assemblyinfo.cs .

    我以前做过,但很快就切换到让 ccnet 将其作为变量传递给 nant。

    【讨论】:

      【解决方案8】:

      看看 SubWCRev - http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-subwcrev.html

      程序集版本号通常在 assemblyinfo.cs 中

      【讨论】:

      • 我添加了一个实现示例作为新答案。
      猜你喜欢
      • 2013-07-16
      • 2014-09-19
      • 2017-04-06
      • 1970-01-01
      • 1970-01-01
      • 2021-01-26
      • 2011-04-22
      • 1970-01-01
      相关资源
      最近更新 更多