2009-06-09 7 views
8

Desidero includere l'ora e la data correnti in un'applicazione .net in modo che possa includerlo nel registro di avvio per mostrare all'utente quale versione hanno. È possibile recuperare l'ora corrente durante la compilazione o dovrei ottenere il tempo di creazione/modifica dell'eseguibile?Come trovo l'ora e la data attuali al momento della compilazione nell'applicazione .net/C#?

E.g.

Benvenuti in ApplicationX. Questo è stato costruito giorno-mese-anno allo tempo.

+0

potrebbe essere che la questione relativa ha una soluzione per voi: http://stackoverflow.com/questions/878037/msbuild- msbuildcommunitytasks-task-time –

+0

è possibile utilizzare [timestamp del linker] (http://stackoverflow.com/questions/2234969/adding-compilation-date-to-code-/2235211#2235211) – user423430

risposta

8

Se si utilizza la riflessione per il numero di build, è possibile utilizzarlo per capire quando è stata compilata una compilazione.

informazioni sulla versione di un assembly è costituito dai seguenti quattro valori:

  1. versione principale
  2. versione minore
  3. numero di build
  4. Revisione

È possibile specificare tutti i valori oppure è possibile accettare il numero di build predefinito, il numero di revisione o entrambi utilizzando un asterisco (*). Il numero di build e la revisione sono basati su Jan 1, 2000 per impostazione predefinita.

Il seguente attributo imposterà maggiore e minore, ma poi incrementerà il numero di build e la revisione.

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

quindi è possibile utilizzare qualcosa di simile:

public static DateTime CompileTime 
{ 
    get 
    { 
     System.Version MyVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; 
     // MyVersion.Build = days after 2000-01-01 
     // MyVersion.Revision*2 = seconds after 0-hour (NEVER daylight saving time) 
     DateTime compileTime = new DateTime(2000, 1, 1).AddDays(MyVersion.Build).AddSeconds(MyVersion.Revision * 2);     
     return compileTime; 
    } 
} 
+0

Penso che la data restituita sia UTC. – Nick

+0

Attualmente lo sto utilizzando con VS2015. Restituisce localtime, ma MinorRevision deve essere castato su ushort se si prevede di generare build dopo le 18:12 (circa). Per gestire l'ora legale, userò GetDaylightChanges, ma non l'ho ancora provato. – jramos

2

Non c'è niente di costruito nel linguaggio per farlo.

È possibile scrivere una fase di pre-compilazione per scrivere la data e l'ora correnti su un file sorgente (in una stringa letterale, ad esempio, o come codice sorgente per generare un DateTime), quindi compilarlo come parte della tua build.

Vorrei suggerire di rendere questo file sorgente il più semplice possibile, non contenente nient'altro che queste informazioni. In alternativa, potrebbe modificare un file esistente.

Per un esempio, consultare il file di build per MiscUtil che incorpora la revisione SVN corrente nell'attributo AssemblyFileVersion. Alcuni pezzi assortiti del file di generazione:

<!-- See http://msbuildtasks.tigris.org --> 
<Import 
Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/> 

<!-- Find out what the latest version is --> 
<SvnInfo RepositoryPath="$(SvnUrl)"> 
    <Output TaskParameter="LastChangedRevision" PropertyName="Revision" /> 
</SvnInfo> 

<!-- Update the AssemblyInfo with the revision number --> 
<FileUpdate Files="$(OutputDirectory)\MiscUtil\MiscUtil\Properties\AssemblyInfo.cs" 
      Regex='(\[\s*assembly:\s*AssemblyFileVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])' 
      ReplacementText='$1.$2.$(Revision)$5' /> 
+0

Grazie per il suggerimento sul assemblaggi ma era solo un po 'più complesso di quanto mi servisse. Dumping informazioni in un file sorgente va bene. – Nick

3

L'unico modo che conosco per farlo è un po 'contorto -

Si può avere un evento di pre-compilazione che gestisce una piccola applicazione che genera il codice sorgente il volo. Un modo semplice per farlo è semplicemente sovrascrivere un file molto piccolo che include una classe (o una classe parziale) con il giorno/mese/anno hardcoded come costante di stringa.

Se si imposta questo come evento di pre-generazione, questo verrà riscritto prima di ogni generazione.

+0

Grazie, questo è quello che ho finito per fare.Ho scritto una piccola app C# che può essere eseguita come una fase di pre-costruzione. – Nick

2

È possibile utilizzare PostSharp per tessere la data immediatamente dopo la creazione. PostSharp è dotato di una libreria di programmazione leggera orientata all'aspetto, ma può essere estesa per intrecciare qualsiasi cosa di cui hai bisogno in un'ampia varietà di modi. Funziona a livello IL, ma l'API ti astrae un po 'da quello.

http://www.postsharp.org/

0

Si potrebbe aggiornare la versione Assemblea in AssemblyInfo.cs come parte della vostra generazione. Allora si potrebbe fare qualcosa di simile

FileVersionInfo lvar = FileVersionInfo.GetVersionInfo(FileName); 

FileVersionInfo ha le informazioni (build/versione, ecc) che si cercano. Vedi se questo funziona per te.

+0

Questo potrebbe funzionare per segnalare alcune cose sull'app, ma l'OP ha chiesto come ottenere data e ora di costruzione. – JeffH

2

In makefiles per i programmi C, è comune vedere qualcosa di simile:

echo char * gBuildSig ="%DATE% %TIME%"; > BuildTimestamp.c 

E poi la fonte C risultante il file è compilato nell'immagine. Quanto sopra funziona su Windows perché le variabili% date% e% time% sono conosciute in cmd.exe, ma una cosa simile funzionerebbe su Unix usando cat.

Si può fare la stessa cosa usando C#. Ancora una volta, questo è come sarebbe se si utilizza un makefile. Hai bisogno di una classe e di una proprietà statica pubblica.

BuildTimestamp.cs: 
    echo public static class Build { public static string Timestamp = "%DATE% %TIME%";} > BuildTimestamp.cs 

E poi per la cosa si sta costruendo, una dipendenza e di eliminazione:

MyApp.exe: BuildTimestamp.cs MyApp.cs 
    $(_CSC) /target:exe /debug+ /optimize- /r:System.dll /out:MyApp.exe MyApp.cs BuildTimestamp.cs 
    -del BuildTimestamp.cs 

Assicurarsi di eliminare il file BuildTimestamp.cs dopo si compila; non vuoi riutilizzarlo Quindi, nella tua app, fai riferimento a Build.Timestamp.

Utilizzando MSBuild o Visual Studio, è più complicato. Non è stato possibile ottenere% date% o% time% da risolvere. Quelle cose sono pseudo variabili d'ambiente, immagino sia per questo. Così ho fatto ricorso a un modo indiretto per ottenere un timestamp, utilizzando l'attività Touch con AlwaysCreate = true. Questo crea un file vuoto. Il passo successivo scrive il codice sorgente nello stesso file, facendo riferimento al timestamp del file. Una svolta: ho dovuto sfuggire al punto e virgola.

Il passo di pre-costruzione dovrebbe creare l'obiettivo "BuildTimestamp". E assicurati di includere quel file nella compilazione. E cancellalo in seguito, nel passaggio post-build.

<ItemGroup> 
    <StampFile Include="BuildTimestamp.cs"/> 
</ItemGroup> 

<Target Name="BuildTimestamp" 
     Outputs="@(StampFile)"> 
    <Message Text="Building timestamp..." /> 

    <Touch 
     AlwaysCreate="true" 
     Files="@(StampFile)" /> 

    <WriteLinesToFile 
     File="@(StampFile)" 
     Lines='public static class Build { public static string Timestamp = "%(StampFile.CreatedTime)" %3B }' 
     Overwrite="true" /> 

</Target> 
0

Ciao ho utilizzato il metodo per la stessa seguente ...

private DateTime ExecutableInfo() 
{ 
    System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath.Trim()); 
    try 
    { 
    return fi.CreationTime; 
    } 
    catch (Exception ex) 
    { 
    throw ex; 
    } 
    finally 
    { 
    fi = null; 
    } 
}