在C#3.0中,我有一个属性,假设包含该类的版本。版本号只是编译的日期和时间。现在,我有以下代码:

public DateTime Version
{
    get { return DateTime.UtcNow; }
}

显然,这是错误的,因为此属性会返回当前日期和时间。 那么,预编译器是否可以在编译时打印 DateTime?在这种情况下,我可以做类似于下面的事情。

public DateTime Version
{
    get { return new DateTime("PRECOMPILER DATE"); }
}
有帮助吗?

解决方案

C#没有宏的概念;但是,您可以在构建脚本(csproj / NANT / etc)中使用其他工具在编译之前操作源代码。例如,我使用它将修订号设置为当前的SVN版本。

廉价选项是预构建事件(您可以通过VS中的项目属性对话框执行此操作):本质上是在构建之前运行的bat文件;然后,您可以编写所需的任何更改。更复杂的选项是构建任务。

例如,实用程序库此处包含 Time 任务和 FileUpdate 任务;它(理论上)应该可以将两者联系起来以模仿你需要的东西。

就个人而言,我会使用 [AssemblyVersion] 的详细信息,而不是时间 - 如果你将它链接到你的源代码控制系统,这样就很容易找到有问题的版本;所以对于我的SVN版本,我然后使用(在我的构建项目中):

<!-- See http://msbuildtasks.tigris.org -->
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
...
<SvnInfo LocalPath=".">
  <Output TaskParameter="Revision" PropertyName="BuildRev" />
</SvnInfo>
...
<FileUpdate Files="Path\To\My\AssemblyInfo.cs"
    Regex='(\[\s*assembly:\s*AssemblyVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])'
    ReplacementText='$1.$2.$(BuildRev)$5' />
<FileUpdate Files="Path\To\My\AssemblyInfo.cs"
    Regex='(\[\s*assembly:\s*AssemblyFileVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])'
    ReplacementText='$1.$2.$(BuildRev)$5' />

现在我的程序集版本是正确的,包括操作系统报告的文件版本。

其他提示

您可以从dll本身检索它( Source:codinghorror

   private DateTime RetrieveLinkerTimestamp() {
        string filePath = System.Reflection.Assembly.GetCallingAssembly().Location;
        const int c_PeHeaderOffset = 60;
        const int c_LinkerTimestampOffset = 8;
        byte[] b = new byte[2048];
        System.IO.Stream s = null;

        try {
            s = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            s.Read(b, 0, 2048);
        } finally {
            if (s != null) {
                s.Close();
            }
        }

        int i = System.BitConverter.ToInt32(b, c_PeHeaderOffset);
        int secondsSince1970 = System.BitConverter.ToInt32(b, i + c_LinkerTimestampOffset);
        DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0);
        dt = dt.AddSeconds(secondsSince1970);
        dt = dt.AddHours(TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours);
        return dt;
    }

C#中的 __ TIME __ 预处理器指令没有等价物,你能做的最好的事情是获取当前程序集并获取创建日期,它将包含编译时间。请参见此处

我认为在C#中没有办法做到这一点 - C ++风格的宏定义明显不允许。

您可以使用程序集的上次修改日期解决此问题,或者可能将文本文件包含为嵌入式资源,并添加将当前日期/时间写入其中的自定义构建操作。

没有预处理器 __ TIME __ 指令,但您可以使用其他内容,例如程序集的创建时间。您也可以考虑使用源代码管理系统中的关键字替换(subversion中的$ Date $)。

可以从以下位置检索构建编号程序集的元数据,可以设置为与构建日期匹配。

通常,您会在AssemblyInfo.cs文件中找到或创建一个条目。使用Visual Studio创建项目时。一个例子:

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

有关 AssemblyVersionAttribute 的文档的引用。 (我加粗了一些重要的部分)

  

您可以指定所有值或您   可以接受默认的内部版本号,   修订号,或两者都使用   星号()。例如,   [组件:的AssemblyVersion(QUOT; 2.3.25.1&QUOT)]   表示2为主要版本,3为   次要版本,25作为构建   数字,1作为修订号。   版本号如   [组件:(&QUOT; 1.2 &QUOT)的AssemblyVersion]   指定1为主要版本,2为   次要版本,并接受   默认构建和修订号。 A.   版本号如   [组件:的AssemblyVersion(&QUOT; 1.2.15 * QUOT)]   指定1为主要版本,2为   次要版本,15作为构建   数字,并接受默认值   修订号。 默认构建   每天增加数量。默认   修订号是随机的。

如您所见,如果您可以使用此设置默认内部版本号。默认的内部版本号是一个每天递增的值。

然后,您可以使用 AssemblyName.Version 属性。 MSDN提供的示例可以帮助您。

默认内部版本号是自2000年1月1日以来的天数。

此问题对如何使用它也有明确的解释。

你在找这样的东西:
(获取通过版本信息构建程序集的日期;构建数字是自1.1.2000以来的天数)

         var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
        DateTime versionsDatum = new DateTime(2000, 1, 1);
        versionsDatum = versionsDatum.AddDays(version.Build);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top