2010-01-12 11 views
45

Come posso recuperare la data creata dall'assembly .NET corrente?Come ottenere la data di un assembly .NET

Vorrei aggiungere alcune funzionalità davvero semplici in cui la mia app smette di funzionare una settimana dopo la data di costruzione dell'assembly principale. Ho già scritto il codice che uccide la mia app dopo una determinata data. Ho solo bisogno di recuperare la data di creazione dall'assembly in modo programmatico.

risposta

41

Non credo che l'assemblea stessa contiene E 'la data di creazione. Sospetto che il più vicino possibile sia la data di creazione del file assembly stesso:

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

dovrebbe fare il trucco.

EDIT:

Credo che la soluzione di Jeff Atwood, redatto dalla "bomba" in questa discussione, è probabilmente il modo migliore per andare.

+8

Funziona nella maggior parte dei casi, ma se si tenta di utilizzarlo nella soluzione VSTO (ad esempio il componente aggiuntivo di Excel), riceverà sempre la data di oggi perché i file di assieme vengono copiati nella cartella AppData \ Local \ assembly prima di eseguire l'aggiunta -in dentro Excel. – surfen

+0

Inoltre non funziona se lo si copia su una rete di download da ftp, ecc. –

+1

Per essere onesti, penso che la soluzione di Jeff Atwood, scritta da granata in questo thread, sia probabilmente il modo migliore per andare ora. –

4

Questo dovrebbe funzionare:

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

cosa c'è di male:

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

Questo è molto meglio perché ho più DLL in fase di aggiornamento. Grazie! –

+3

Molto meglio. 'GetCreationTime()' restituisce l'ora in cui l'assembly è stato PRIMO creato. Questo non restituisce il tempo in cui l'assembly è stato creato ULTIMO. – Jop

2

Il modo migliore per farlo sarebbe con un attributo personalizzato impostato su PreBuild dell'assieme.

E quindi utilizzare la riflessione standard per ottenere l'attributo creato.

Ma per curiosità, perché uccidere l'app dopo la data di COSTRUZIONE?

+0

Non è necessario che sia la data di costruzione. Ho appena scelto quella data perché sapevo che la data sarebbe cambiata automaticamente con la costruzione dell'app. L'obiettivo, voglio solo consentire all'applicazione di funzionare per circa una settimana.Potrei anche effettuare l'hardcode di una data nel codice, ma avrei dovuto modificare quella variabile mentre le modifiche venivano apportate all'app. – DenaliHardtail

+0

@Scott, ma il modo per uccidere l'app, è facilmente aggirabile. –

+1

Uccidere l'app in base alla data di costruzione sembra un buon modo per ridurre il rumore quando si eseguono test alfa in un ambiente non strutturato (ad esempio i volontari di Internet). In questo modo si evita che le persone scarichino l'alpha più recente, dimenticandolo per 3 settimane, e poi testando e segnalando molti bug che sono già stati risolti. Assicura che gli alpha tester utilizzino sempre una versione recente dell'app, senza avere qualcosa che potrebbe introdurre ancora più bug in quella fase come una funzione di aggiornamento automatico. – David

9

Forse questo post on coding horror può aiutare

+0

+1 Ha funzionato alla grande! – devios1

+0

Questo link è morto. –

+0

collegamento aggiornato, sebbene molte altre risposte qui facciano la stessa cosa o facciano riferimento a questa nuova posizione articoli – jmlumpkin

56

Di seguito si basa su: 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

Questo rende un buon metodo di estensione sulla classe Assembly. –

+1

Non funziona per gli assiemi creati tramite reflection (in memoria). Quelli non hanno una posizione (stringa vuota). –

+19

Non mi aspetto di trovare una data di compilazione su un assembly in memoria proprio come non mi aspetterei di trovare strisce zebra su un pony. – grenade

1

Se si scrive una domanda di un dispositivo mobile utilizzando il framwork compatto, Assembly.Location non è disponibile .

Here, ho trovato un'alternativa:

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