Come posso ottenere l'attuale DateTime dal precompilatore in C #?
-
03-07-2019 - |
Domanda
In C # 3.0, ho una proprietà che dovrebbe contenere la versione della classe. Il numero di versione è semplicemente la data e l'ora della compilazione. In questo momento, ho il seguente codice:
public DateTime Version
{
get { return DateTime.UtcNow; }
}
Ovviamente, questo è sbagliato poiché questa proprietà mi restituisce la data e l'ora correnti. Quindi, il precompilatore può stampare il DateTime al momento della compilazione? In questo caso, potrei fare qualcosa di simile al seguente.
public DateTime Version
{
get { return new DateTime("PRECOMPILER DATE"); }
}
Soluzione
C # non ha il concetto di macro; tuttavia, è possibile utilizzare altri strumenti nello script di compilazione (csproj / NANT / etc) per manipolare l'origine prima che venga compilata. Uso questo, ad esempio, per impostare il numero di revisione sull'attuale revisione SVN.
Un'opzione economica è un evento pre-build (puoi farlo tramite la finestra di dialogo delle proprietà del progetto in VS): essenzialmente un file bat che viene eseguito prima della build; puoi quindi scrivere qualunque cambiamento tu abbia bisogno. Un'opzione più sofisticata è costruire attività.
Ad esempio, la libreria di utilità qui include un'attività Time
e un FileUpdate
; dovrebbe (in teoria) essere possibile unire le due cose per emulare ciò di cui hai bisogno.
Personalmente, userei i dettagli [AssemblyVersion]
piuttosto che il tempo - se lo colleghi al tuo sistema di controllo del codice sorgente, sarà molto facile trovare la versione offensiva; quindi per la mia versione SVN, uso quindi (nel mio build proj):
<!-- See http://msbuildtasks.tigris.org -->
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
...
<SvnInfo LocalPath=".">
<Output TaskParameter="Revision" PropertyName="BuildRev" />
</SvnInfo>
...
<FileUpdate Files="Path\To\My\AssemblyInfo.cs"
Regex='(\[\s*assembly:\s*AssemblyVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])'
ReplacementText='$1.$2.$(BuildRev)$5' />
<FileUpdate Files="Path\To\My\AssemblyInfo.cs"
Regex='(\[\s*assembly:\s*AssemblyFileVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])'
ReplacementText='$1.$2.$(BuildRev)$5' />
E ora la mia versione dell'assembly è corretta, inclusa la versione del file che viene segnalata dal sistema operativo.
Altri suggerimenti
Puoi recuperarlo dalla dll stessa ( Fonte: codinghorror )
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;
}
Non esiste un equivalente per la direttiva preprocessore __TIME__
in C #, Il meglio che puoi fare è ottenere l'assembly corrente e ottenere la data di creazione, conterrà il tempo di compilazione. Vedi qui
Non credo che ci sia un modo per farlo in C # - Le definizioni di macro in stile C ++ sono esplicitamente vietate.
È possibile aggirare il problema utilizzando la data dell'ultima modifica dell'assembly oppure includere potenzialmente un file di testo come risorsa incorporata e aggiungere un'azione di compilazione personalizzata che vi scriva la data / ora corrente.
Non esiste una direttiva __TIME__
sul preprocessore, ma ci sono altre cose che potresti usare, come il tempo di creazione dell'assembly. Puoi anche prendere in considerazione l'utilizzo della sostituzione delle parole chiave dal tuo sistema di controllo del codice sorgente ($ Date $ in sovversione).
Il Build può essere recuperato da i metadati di un assembly e possono essere impostati in modo che corrispondano alla data della build.
In genere è possibile trovare o creare una voce nel file AssemblyInfo.cs. Quando il progetto viene creato utilizzando Visual Studio. Un esempio:
[assembly: AssemblyVersion("1.0.*")]
Un preventivo per la documentazione su AssemblyVersionAttribute . (Ho messo in grassetto alcune parti importanti)
Puoi specificare tutti i valori o te può accettare il numero di build predefinito, numero di revisione, o entrambi usando un asterisco (). Per esempio, [Assembly: AssemblyVersion (" 2.3.25.1 ")] indica 2 come versione principale, 3 come la versione secondaria, 25 come build numero e 1 come numero di revisione. Un numero di versione come [Assembly: (. & Quot; 1.2 ") AssemblyVersion] specifica 1 come versione principale, 2 come la versione secondaria e accetta il numeri di build e revisione predefiniti. A numero di versione come [Assembly: AssemblyVersion (. & Quot; 1.2.15 * ")] specifica 1 come versione principale, 2 come la versione secondaria, 15 come build numero e accetta il valore predefinito numero di revisione. La build predefinita il numero aumenta ogni giorno. Il predefinito il numero di revisione è casuale.
Come puoi vedere, se puoi impostare un numero di build predefinito con questo. Il numero di build predefinito è un valore che viene incrementato ogni giorno.
È quindi possibile recuperare il numero di build utilizzando AssemblyName.Version . Gli esempi forniti da MSDN dovrebbero aiutarti.
Il numero di build predefinito è il numero di giorni dall'1 / 1/2000.
Questa domanda ha anche una chiara spiegazione su come usarlo.
Cerchi qualcosa del genere:
(Ottieni la data di creazione dell'assemblaggio tramite le informazioni sulla versione; il numero di build è giorni dall'1.1.2000)
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
DateTime versionsDatum = new DateTime(2000, 1, 1);
versionsDatum = versionsDatum.AddDays(version.Build);