2009-01-07 5 views
6

In C# 3.0 habe ich eine Eigenschaft, die die Version der Klasse enthalten soll. Die Versionsnummer ist einfach das Datum und die Uhrzeit der Kompilierung. Gerade jetzt, ich habe den folgenden Code:Wie kann ich die aktuelle DateTime vom Precompiler in C# abrufen?

public DateTime Version 
{ 
    get { return DateTime.UtcNow; } 
} 

Offensichtlich ist dies falsch, da diese Eigenschaft gibt mir das aktuelle Datum und die Uhrzeit. Also, kann der Precompiler die DateTime zur Kompilierzeit drucken? In diesem Fall könnte ich etwas ähnliches wie unten tun.

public DateTime Version 
{ 
    get { return new DateTime("PRECOMPILER DATE"); } 
} 

Antwort

7

C# hat nicht das Konzept von Makros; Sie können jedoch andere Tools in Ihrem Buildskript (csproj/NANT/etc) verwenden, um die Quelle vor dem Kompilieren zu bearbeiten. Ich verwende dies zum Beispiel, um die Revisionsnummer auf die aktuelle SVN-Revision zu setzen.

Eine billige Option ist ein Pre-Build-Event (Sie können dies über den Projekteigenschaften-Dialog in VS tun): im Wesentlichen eine Bat-Datei, die vor dem Build läuft; Sie können dann die gewünschten Änderungen durchführen. Eine anspruchsvollere Option sind Build-Aufgaben.

Zum Beispiel enthält die Dienstprogrammbibliothek here eine Time Aufgabe und eine FileUpdate Aufgabe; Es sollte (theoretisch) möglich sein, die beiden zusammen zu ketten, um zu emulieren, was Sie brauchen.

Persönlich würde ich die [AssemblyVersion] Details lieber als die Zeit verwenden - wenn Sie dies mit Ihrer Source-Control-System verknüpfen, macht es sehr einfach, die problematische Version zu finden; so für meine SVN-Version benutze ich dann (in meinem 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' /> 

Und jetzt meine Montag-Version korrekt ist, einschließlich der Datei-Version, die von den OS gemeldet wird.

+0

ich etwas tun ähnlich dazu in MSBuild mit den Microsoft SDC-Aufgaben unter: http://www.codeplex.com/sdctasks –

3

Es gibt keine Entsprechung für die Präprozessordirektive __TIME__ in C#. Das Beste, was Sie tun können, ist, die aktuelle Assembly zu holen und das Erstellungsdatum zu erhalten, es enthält die Kompilierzeit. Siehe here

0

Ich glaube nicht, dass es eine Möglichkeit gibt, dies in C# zu tun - C++ - Makrodefinitionen sind explizit nicht erlaubt.

Sie können das letzte Änderungsdatum der Assembly umgehen oder eine Textdatei als eingebettete Ressource einfügen und eine benutzerdefinierte Buildaktion hinzufügen, die das aktuelle Datum/die aktuelle Uhrzeit in die Assembly schreibt.

0

Es gibt keine Präprozessor __TIME__ Direktive, aber es gibt andere Dinge, die Sie verwenden könnten, wie die Erstellungszeit der Baugruppe. Sie können auch eine Schlüsselwortersetzung von Ihrem Quellcodeverwaltungssystem ($ Date $ in Subversion) in Betracht ziehen.

8

Sie können es von der DLL selbst (Source: 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; 
    } 
+0

Interessanter Link ... Danke. –

+0

Gern geschehen :) – Stormenet

+1

Was noch schöner ist, funktioniert das sogar auf Monotouch. –

-1

Die Build Nummer retreive aus den Metadaten einer Baugruppe abgerufen werden können, und eingestellt werden kann, mit dem Datum des Builds anzupassen.

Normalerweise finden oder erstellen Sie einen Eintrag in der Datei AssemblyInfo.cs. Wenn Ihr Projekt mit Visual Studio erstellt wird.Ein Beispiel:

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

Ein Zitat für die Dokumentation auf AssemblyVersionAttribute. (Ich habe ein paar wichtige Teile bolded)

Sie alle Werte angeben können, oder Sie können die Standard-Build-Nummer, Revisionsnummer akzeptieren oder beide durch ein Sternchen mit (). Beispiel: [assembly: AssemblyVersion ("2.3.25.1")] bedeutet 2 als Hauptversion, 3 als die Nebenversion, 25 als Build Nummer und 1 als Revisionsnummer. Eine Versionsnummer wie [assembly: Assembly („1.2“)] gibt 1 als die Hauptversion, 2 als die Nebenversion, und akzeptiert die Standard-Build und Revisionsnummern. A Versionsnummer wie [assembly: Assembly ("1.2.15. *")] gibt 1 als die Hauptversion, 2 als die kleinere Version, 15 als Build Nummer und übernimmt die Standard Revision Nummer. Der Standard Build Nummer erhöht sich täglich. Die Standard-Versionsnummer ist zufällig.

Wie Sie sehen können, wenn Sie eine Standard-Build-Nummer mit diesem festlegen können. Die Standard-Build-Nummer ist ein Wert, der jeden Tag erhöht wird.

Sie können die Build-Nummer dann mithilfe der AssemblyName.Version-Eigenschaft abrufen. Die Beispiele von MSDN sollten Sie in Gang bringen.

Die Standard-Build-Nummer ist die Anzahl der Tage seit dem 1.1.2000.

This question hat auch eine klare Erklärung, wie man das benutzt.

+0

Das ist nicht wahr, die Build-Nummer kann alles sein, was Sie wollen, und würde sich wahrscheinlich ändern, wenn Sie tatsächlich Releases machen. Sie können sich nicht auf Ihre Build-Nummer verlassen, um zu wissen, wann die Kompilierung stattgefunden hat. –

+0

Ja, die Build-Nummer kann alles sein, was Sie wollen, aber die Standard-Build-Nummer, die mit dem "*" in der Version generiert wird, ist die Anzahl der Tage seit 01.01.2000 – GvS

+0

Ich habe meine Antwort mehr gemacht klar. Ich hoffe, jetzt gibt es keine Verwechslung zwischen der User-Set-Build-Nummer und der generierten Standard-Build-Nummer. – GvS

-1

Haben Sie auf der Suche nach so etwas wie folgt aus:
(Get ist das Datum der Bau der Versammlung über Version-Info; Errichten-Anzahl Tage seit dem 1.1.2000 ist)

  var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; 
     DateTime versionsDatum = new DateTime(2000, 1, 1); 
     versionsDatum = versionsDatum.AddDays(version.Build); 
Verwandte Themen