获取.NET程序集的日期

Den*_*ail 50 c# .net-3.5

如何从当前.NET程序集中检索创建日期?

我想添加一些简单的功能,我的应用程序在主程序集的构建日期后一周停止工作.我已经编写了在给定日期之后杀死我的应用程序的代码.我只需要以编程方式从程序集中检索创建日期.

gre*_*ade 57

以下内容基于:https://blog.codinghorror.com/determining-build-date-the-hard-way/

public static class ApplicationInformation
{
    /// <summary>
    /// Gets the executing assembly.
    /// </summary>
    /// <value>The executing assembly.</value>
    public static System.Reflection.Assembly ExecutingAssembly
    {
        get { return executingAssembly ?? (executingAssembly = System.Reflection.Assembly.GetExecutingAssembly()); }
    }
    private static System.Reflection.Assembly executingAssembly;

    /// <summary>
    /// Gets the executing assembly version.
    /// </summary>
    /// <value>The executing assembly version.</value>
    public static System.Version ExecutingAssemblyVersion
    {
        get { return executingAssemblyVersion ?? (executingAssemblyVersion = ExecutingAssembly.GetName().Version); }
    }
    private static System.Version executingAssemblyVersion;

    /// <summary>
    /// Gets the compile date of the currently executing assembly.
    /// </summary>
    /// <value>The compile date.</value>
    public static System.DateTime CompileDate
    {
        get
        {
            if (!compileDate.HasValue)
                compileDate = RetrieveLinkerTimestamp(ExecutingAssembly.Location);
            return compileDate ?? new System.DateTime();
        }
    }
    private static System.DateTime? compileDate;

    /// <summary>
    /// Retrieves the linker timestamp.
    /// </summary>
    /// <param name="filePath">The file path.</param>
    /// <returns></returns>
    /// <remarks>http://www.codinghorror.com/blog/2005/04/determining-build-date-the-hard-way.html</remarks>
    private static System.DateTime RetrieveLinkerTimestamp(string filePath)
    {
        const int peHeaderOffset = 60;
        const int linkerTimestampOffset = 8;
        var b = new byte[2048];
        System.IO.FileStream 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();
        }
        var dt = new System.DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(System.BitConverter.ToInt32(b, System.BitConverter.ToInt32(b, peHeaderOffset) + linkerTimestampOffset));
        return dt.AddHours(System.TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我不希望在内存汇编中找到编译日期,就像我不希望在小马上找到斑马条纹一样. (21认同)
  • 我喜欢这个,我最近唯一的变化是它在一个时区编译但在另一个时区部署(例如:在Build Server上编译并部署到Azure).在这种情况下,我修改了最后两行,如下所示:'var dateUtcKind = DateTime.SpecifyKind(dt,DateTimeKind.Utc); return dateUtcKind;' (4认同)
  • 不适用于通过反射(在内存中)创建的程序集。那些没有位置(空字符串)。 (2认同)

Rob*_*ine 47

我不认为程序集本身包含它的创建日期.我怀疑你能得到的最接近的是汇编文件本身的创建日期:

File.GetCreationTime(Assembly.GetExecutingAssembly().Location)
Run Code Online (Sandbox Code Playgroud)

应该做的伎俩.

编辑:

我认为杰夫阿特伍德的解决方案,在这个线程中由"手榴弹"编写,可能是现在更好的方法.

  • 它适用于大多数情况,但如果试图在VSTO解决方案中使用它(例如Excel加载项),他将始终获得今天的日期,因为在运行添加之前,程序集文件被复制到AppData\Local\assembly文件夹中在Excel里面. (8认同)
  • `GetLastWriteTime()`在构建时会更准确.`GetCreationTime()`只会返回清理项目后创建的第一个构建 (3认同)

Wim*_*dse 29

有什么不对:

System.IO.File.GetLastWriteTime(Assembly.GetExecutingAssembly().Location);
Run Code Online (Sandbox Code Playgroud)

  • 好多了.`GetCreationTime()`返回第一次创建程序集的时间.这不会返回最后一次创建程序集的时间. (3认同)

jml*_*kin 9

也许关于编码恐怖的这篇文章可能有所帮助


Jak*_*son 5

这应该工作:

var entryAssembly = Assembly.GetEntryAssembly();
var fileInfo = new FileInfo(entryAssembly.Location);
var buildDate = fileInfo.LastWriteTime;
Run Code Online (Sandbox Code Playgroud)