一尘不染

显示构建日期

c#

我目前有一个应用程序,在其标题窗口中显示内部版本号。那是好事,只是对大多数用户没有任何意义,他们想知道他们是否拥有最新的版本-
他们倾向于将其称为“上周四”,而不是版本1.0.8.4321。

计划是将构建日期放在此处-因此,例如“ App建筑于2009年10月21日”。

我正在努力寻找一种编程方式来将构建日期作为文本字符串提取出来,以供使用。

对于内部版本号,我使用了:

Assembly.GetExecutingAssembly().GetName().Version.ToString()

在定义了这些内容之后。

我想要类似的东西作为编译日期(和时间,以获得加分)。

非常感谢这里的指针(如果适当的话,请使用双关语)或更整洁的解决方案…


阅读 323

收藏
2020-05-19

共1个答案

一尘不染

Jeff Atwood在“ 确定构建日期”这一难题上有几句话要说。

事实证明,最可靠的方法是从嵌入在可执行文件中的PE标头中检索链接器时间戳记-
某些C#代码(由Joe Spivey提供)用于从对Jeff的评论中获得的注释:

public static DateTime GetLinkerTime(this Assembly assembly, TimeZoneInfo target = null)
{
    var filePath = assembly.Location;
    const int c_PeHeaderOffset = 60;
    const int c_LinkerTimestampOffset = 8;

    var buffer = new byte[2048];

    using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        stream.Read(buffer, 0, 2048);

    var offset = BitConverter.ToInt32(buffer, c_PeHeaderOffset);
    var secondsSince1970 = BitConverter.ToInt32(buffer, offset + c_LinkerTimestampOffset);
    var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

    var linkTimeUtc = epoch.AddSeconds(secondsSince1970);

    var tz = target ?? TimeZoneInfo.Local;
    var localTime = TimeZoneInfo.ConvertTimeFromUtc(linkTimeUtc, tz);

    return localTime;
}

用法示例:

var linkTimeLocal = Assembly.GetExecutingAssembly().GetLinkerTime();

更新:该方法适用于.Net Core 1.0,但 在.Net Core 1.1 发布 后停止了工作 (给出了1900-2020年的随机年份)

2020-05-19