2010-01-12 57 views
45

如何從當前.NET程序集中檢索創建日期?獲取.NET程序集的日期

我想添加一些真正簡單的功能,其中我的應用程序在主程序集生成日期一週後停止工作。我已經寫了在特定日期後殺死我的應用程序的代碼。我只需要以編程方式從程序集中檢索創建日期。

回答

41

我不認爲大會本身包含它的創建日期。我懷疑最接近你可以得到的是彙編文件本身的創建日期:

File.GetCreationTime(Assembly.GetExecutingAssembly().Location) 

應該做的伎倆。

編輯:

我認爲傑夫·阿特伍德的解決方案,通過「手榴彈」在這個線程寫上去,可能是更好的方式走了。

+8

它在大多數情況下都能正常工作,但是如果有人試圖在VSTO解決方案中使用它(例如Excel插件),他總會得到Today's date,因爲在運行add之前將程序集文件複製到AppData \ Local \ assembly文件夾中在Excel裏面。 – surfen 2012-07-27 10:54:17

+0

如果您將其複製到從ftp等下載的網絡中,也無法正常工作 – 2013-05-29 15:16:25

+1

說實話,我認爲傑夫阿特伍德的解決方案在此主題中由手榴彈編寫,可能是現在更好的方法。 – 2013-05-30 12:41:09

4

這應該工作:

var entryAssembly = Assembly.GetEntryAssembly(); 
var fileInfo = new FileInfo(entryAssembly.Location); 
var buildDate = fileInfo.LastWriteTime; 
22

出了什麼問題:

System.IO.File.GetLastWriteTime(Assembly.GetExecutingAssembly().Location); 
+0

這是好多了,因爲我有多個DLL文件被更新。謝謝! – 2014-01-30 23:39:18

+3

好多了。 'GetCreationTime()'返回程序集第一次創建的時間。這不會返回程序集最後創建的時間。 – Jop 2014-04-25 07:59:30

2

要做到這一點的最佳方法是使用您在程序集的PreBuild上設置的自定義屬性。

然後使用標準反射來獲取您創建的屬性。

但出於好奇,爲什麼要在構建日期後終止應用程序?

+0

不需要是生成日期。我只是選擇了這個日期,因爲我知道這個日期會隨着應用程序的建立而自動改變。目標,我只想讓應用程序運行約一週。我也可以將日期硬編碼到代碼中,但需要在對應用程序進行更改時更改該變量。 – DenaliHardtail 2010-01-12 16:28:07

+0

@Scott,但比你的方式殺死應用程序,很容易規避。 – 2010-01-12 17:35:08

+1

在非結構化環境(例如互聯網誌願者)中進行alpha測試時,基於構建日期來殺死應用程序似乎是減少噪聲的好方法。這樣可以避免人們下載最新的alpha版本,將其遺忘3周,然後測試並報告已經處理的大量錯誤。它可以確保阿爾法測試人員始終使用最新版本的應用程序,而無需在該階段引入更多錯誤,例如自動更新功能。 – David 2010-01-12 19:22:37

9

也許這篇文章on coding horror可以幫助

+0

+1這很棒! – devios1 2010-08-07 03:33:06

+0

此鏈接已死亡。 – 2014-05-08 23:02:39

+0

已更新的鏈接,雖然其他幾個答案在這裏做相同的事情或參考這篇文章新的位置 – jmlumpkin 2014-05-16 15:52:02

56

以下是基於: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); 
    } 
} 
+0

這使得Assembly類的一個很好的擴展方法。 – 2013-02-20 22:11:20

+1

不適用於通過反射創建的程序集(在內存中)。那些沒有位置(空字符串)。 – 2014-03-10 20:52:15

+19

我不希望在內存組件上找到編譯日期,就像我不希望在小馬上找到斑馬條紋一樣。 – grenade 2014-03-11 05:17:06

1

如果你正在編寫使用小型framwork移動設備的應用程序,Assembly.Location不可用。

Here,我發現了一個選擇:

 System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)