【问题标题】:How can I get the assembly last modified date?如何获取程序集的最后修改日期?
【发布时间】:2010-10-22 16:43:07
【问题描述】:

我想呈现(用于内部调试/信息)程序集的最后修改日期,所以我会知道某个网站何时部署。

是否可以通过反射得到它?

我得到这样的版本:

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

我正在寻找类似的东西——我不想打开物理文件、获取它的属性或类似的东西,因为我将在母版页中呈现它,并且不想要那个有点开销。

【问题讨论】:

    标签: .net asp.net reflection file-properties modified-date


    【解决方案1】:

    我会第二次 pYrania 的回答:

    System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
    System.IO.FileInfo fileInfo = new System.IO.FileInfo(assembly.Location);
    DateTime lastModified = fileInfo.LastWriteTime;
    

    但是添加这个:

    您提到您不想访问文件系统,因为它位于您的母版页中,并且您不想为每个页面都点击额外的文件系统。所以不要,只需在应用程序加载事件中访问一次,然后将其存储为应用程序级变量。

    【讨论】:

    • 嗨,我尝试使用此代码,但出现位置错误。在我的情况下,位置即将为空......所以,我该怎么办?
    • @Jignesh.Raj 一定要检查 if (assembly != null) { ... }if (fileInfo != null) { ... } 以节省一些悲伤。
    • 只要您不在 Xamarin Android 上以 RELEASE 模式使用它,它就可以完美运行。它总是返回 1601 年 1 月 1 日作为日期。
    【解决方案2】:

    如果您在 AssemblyInfo 中默认修订和内部版本号:

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

    您可以通过以下方式获得大致的构建日期:

    Version version = typeof(MyType).Assembly.GetName().Version;
    DateTime date = new DateTime(2000, 1, 1)
        .AddDays(version.Build)
        .AddSeconds(version.Revision * 2);
    

    【讨论】:

    • Hallgrim 的回答也很有效。只要确保您修改的是程序集版本,而不是文件版本 (oops)
    • 如果您在承载 Web 部件的 SharePoint 程序集中使用它,请小心,因为 SP 将向(用户)显示 Web 部件的错误,这些 Web 部件是从其版本的程序集添加到页面的数字从此改变。否则,这是一个很好的答案。
    【解决方案3】:

    这个怎么样?

    System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
    System.IO.FileInfo fileInfo = new System.IO.FileInfo(assembly.Location);
    DateTime lastModified = fileInfo.LastWriteTime;
    

    【讨论】:

      【解决方案4】:

      有些人认为 Assembly 没有构建日期,但您知道他们错在哪里, 您可以从嵌入在可执行文件中的PE header 中检索链接器时间戳,如下所示可能有效(我自己没有测试过代码)

      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;
      }
      

      或者如果组装是您自己的更好,您可以使用以下简单易行的方法

      在预构建事件命令行中添加以下内容:

      echo %date% %time% > "$(ProjectDir)\Resources\BuildDate.txt"
      

      将此文件添加为资源,现在您的资源中有“BuildDate”字符串。

      我已经从this question得到了两个答案

      【讨论】:

      【解决方案5】:

      RetrieveLinkerTimestamp 解决方案在2038 之后将不起作用,因为使用了来自1970int32。我建议使用以下内容(尽管这可能也有其局限性):

      IO.File.GetLastWriteTime(Reflection.Assembly.GetExecutingAssembly().Location)
      

      【讨论】:

        【解决方案6】:

        我不相信程序集包含最后修改的信息,因为这是操作系统属性。我相信获取此信息的唯一方法是通过文件句柄。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多