如何在编译时在.net / C#应用程序中找到当前时间和日期?

时间:2009-06-09 17:38:50

标签: c# build clr

我想在.net应用程序中包含当前时间和日期,以便将其包含在启动日志中以向用户显示他们拥有的版本。是否可以在编译期间检索当前时间,或者我是否必须获得可执行文件的创建/修改时间?

E.g。

  

欢迎使用ApplicationX。这是在时间建立的日 - 月 -

7 个答案:

答案 0 :(得分:9)

如果您使用反射作为您的内部版本号,您可以使用它来确定编译构建的时间。

程序集的版本信息包含以下四个值:

  1. 主要版本
  2. 次要版本
  3. 内部版本号
  4. 修订
  5. 您可以指定所有值,也可以使用星号(*)接受默认的内部版本号,修订号或两者。内部版本号和修订版默认基于2000年1月1日。

    以下属性将设置Major和minor,但随后会增加内部版本号和修订版。

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

    然后你可以使用这样的东西:

    public static DateTime CompileTime
    {
       get
       {
          System.Version MyVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
          // MyVersion.Build = days after 2000-01-01
          // MyVersion.Revision*2 = seconds after 0-hour  (NEVER daylight saving time)
          DateTime compileTime = new DateTime(2000, 1, 1).AddDays(MyVersion.Build).AddSeconds(MyVersion.Revision * 2);                
          return compileTime;
       }
    }
    

答案 1 :(得分:3)

我知道这样做的唯一方法有点令人费解 -

您可以拥有一个预构建事件,该事件运行一个小型应用程序,可以动态生成源代码。一种简单的方法是覆盖一个非常小的文件,该文件包含一个类(或部分类),其中日/月/年硬编码为字符串常量。

如果将其设置为预构建事件,则会在每次构建之前重写该文件。

答案 2 :(得分:2)

这种语言没有内置任何东西。

您可以编写一个预构建步骤来写出源文件的当前日期和时间(例如,在字符串文字中,或者作为生成DateTime的源代码),然后编译这是你构建的一部分。

我建议你让这个源文件尽可能简单,只包含这些信息。或者,可以编辑现有文件。

有关此示例,请参阅MiscUtil的构建文件,该文件将当前SVN修订版嵌入到AssemblyFileVersion属性中。构建文件的一些不同部分:

<!-- See http://msbuildtasks.tigris.org -->
<Import 
 Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>

<!-- Find out what the latest version is -->
<SvnInfo RepositoryPath="$(SvnUrl)">
  <Output TaskParameter="LastChangedRevision" PropertyName="Revision" />
</SvnInfo>

<!-- Update the AssemblyInfo with the revision number -->
<FileUpdate Files="$(OutputDirectory)\MiscUtil\MiscUtil\Properties\AssemblyInfo.cs"
            Regex='(\[\s*assembly:\s*AssemblyFileVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])'
            ReplacementText='$1.$2.$(Revision)$5' />

答案 3 :(得分:2)

您可以使用PostSharp在构建后立即编织日期。 PostSharp带有一个轻量级的面向方面的编程库,但它可以扩展到以各种方式编织你需要的任何东西。它适用于IL级别,但API会从中抽象出来。

http://www.postsharp.org/

答案 4 :(得分:2)

在C程序的makefile中,通常会看到类似这样的内容:

echo char * gBuildSig ="%DATE% %TIME%"; > BuildTimestamp.c

然后将生成的C源文件编译到图像中。以上适用于Windows,因为%date%和%time%变量在cmd.exe中是已知的,但类似的东西在使用cat的Unix上也可以。

你可以使用C#做同样的事情。再一次,这就是你使用makefile时的样子。您需要一个类和一个公共静态属性。

BuildTimestamp.cs: 
    echo public static class Build { public static string Timestamp = "%DATE% %TIME%";} > BuildTimestamp.cs 

然后对于您正在构建的内容,依赖项和删除:

MyApp.exe: BuildTimestamp.cs MyApp.cs
    $(_CSC)  /target:exe /debug+ /optimize- /r:System.dll /out:MyApp.exe MyApp.cs BuildTimestamp.cs
    -del  BuildTimestamp.cs

确保在编译后删除BuildTimestamp.cs文件;你不想重复使用它。然后,在您的应用程序中,只需引用Build.Timestamp。

使用MSBuild或Visual Studio,它更复杂。我无法获得%date%或%time%来解决。那些东西都是伪环境变量,我猜这就是原因。因此,我使用带有AlwaysCreate = true的Touch任务,采用间接方式获取时间戳。这会创建一个空文件。下一步将源代码写入同一文件,引用文件的时间戳。一个转折 - 我不得不逃脱分号。

您的预构建步骤应构建目标“BuildTimestamp”。并确保将该文件包含在编译中。然后在后构建步骤中删除它。

<ItemGroup>
  <StampFile   Include="BuildTimestamp.cs"/>
</ItemGroup>

<Target Name="BuildTimestamp" 
        Outputs="@(StampFile)">
  <Message Text="Building timestamp..." />

  <Touch
        AlwaysCreate="true"
        Files="@(StampFile)" />

  <WriteLinesToFile
        File="@(StampFile)"
        Lines='public static class Build { public static string Timestamp = "%(StampFile.CreatedTime)" %3B }'
        Overwrite="true" />

</Target>

答案 5 :(得分:0)

您可以在AssemblyInfo.cs中更新Assembly版本,作为构建的一部分。然后你可以做这样的事情

FileVersionInfo lvar = FileVersionInfo.GetVersionInfo(FileName);

FileVersionInfo包含您要查找的信息(版本/版本等)。看看这是否适合您。

答案 6 :(得分:0)

您好我使用以下方法...

private DateTime ExecutableInfo()
{
  System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath.Trim());
  try
  {
    return fi.CreationTime;
  }
  catch (Exception ex)
  {
    throw ex;
  }
  finally
  {
    fi = null;
  }
}