Ich habe derzeit eine App, die die Build-Nummer in ihrem Titelfenster anzeigt. Das ist gut und schön, außer dass es für die meisten Benutzer, die wissen möchten, ob sie den neuesten Build haben, nichts bedeutet. Sie bezeichnen ihn eher als "letzten Donnerstag" als als Build 1.0.8.4321.
Es ist geplant, stattdessen das Erstellungsdatum dort anzugeben - also zum Beispiel "App erstellt am 21.10.2009".
Ich habe Probleme, einen programmatischen Weg zu finden, um das Erstellungsdatum als Textzeichenfolge für eine solche Verwendung herauszuholen.
Für die Build-Nummer habe ich verwendet:
Assembly.GetExecutingAssembly().GetName().Version.ToString()
nachdem definiert wurde, wie diese entstanden sind.
Ich möchte so etwas für das Kompilierungsdatum (und die Uhrzeit für Bonuspunkte).
Zeiger hier sehr geschätzt (entschuldigen Sie Wortspiel, falls zutreffend) oder sauberere Lösungen ...
quelle
Antworten:
Jeff Atwood hatte ein paar Dinge zu diesem Problem zu sagen, indem er auf die harte Tour das Erstellungsdatum festlegte .
Die zuverlässigste Methode ist das Abrufen des Linker-Zeitstempels aus dem in die ausführbare Datei eingebetteten PE-Header - ein C # -Code (von Joe Spivey) dafür aus den Kommentaren zu Jeffs Artikel:
Anwendungsbeispiel:
UPDATE: Die Methode funktionierte für .Net Core 1.0, funktionierte jedoch nach der Veröffentlichung von .Net Core 1.1 nicht mehr (gibt zufällige Jahre im Bereich von 1900 bis 2020 an).
quelle
.AddHours()
ist ziemlich hackisch und (glaube ich) wird die Sommerzeit nicht berücksichtigen. Wenn Sie es in der Ortszeit möchten, sollten Siedt.ToLocalTime();
stattdessen den Reiniger verwenden. Der Mittelteil könnte auch mit einemusing()
Block stark vereinfacht werden .Fügen Sie der Befehlszeile für vorgefertigte Ereignisse Folgendes hinzu:
Fügen Sie diese Datei als Ressource hinzu. Jetzt haben Sie die Zeichenfolge 'BuildDate' in Ihren Ressourcen.
Informationen zum Erstellen von Ressourcen finden Sie unter Erstellen und Verwenden von Ressourcen in .NET .
quelle
Der Weg
Wie von @ c00000fd in den Kommentaren hervorgehoben . Microsoft ändert dies. Und obwohl viele Leute nicht die neueste Version ihres Compilers verwenden, vermute ich, dass diese Änderung diesen Ansatz zweifellos schlecht macht. Und während es eine lustige Übung ist, würde ich Leuten empfehlen, einfach ein Erstellungsdatum in ihre Binärdatei einzubetten, wenn es wichtig ist, das Erstellungsdatum der Binärdatei selbst zu verfolgen.
Dies kann mit einer trivialen Codegenerierung erfolgen, die wahrscheinlich bereits der erste Schritt in Ihrem Build-Skript ist. Das und die Tatsache, dass ALM / Build / DevOps-Tools dabei sehr hilfreich sind und allen anderen vorgezogen werden sollten.
Den Rest dieser Antwort lasse ich hier nur zu historischen Zwecken.
Der neue Weg
Ich habe es mir anders überlegt und verwende derzeit diesen Trick, um das richtige Erstellungsdatum zu erhalten.
Der alte Weg
Wie generieren Sie Build-Nummern? Visual Studio (oder der C # -Compiler) bietet tatsächlich automatische Build- und Revisionsnummern, wenn Sie das AssemblyVersion-Attribut in z
1.0.*
Was passieren wird, ist, dass der Build der Anzahl der Tage seit dem 1. Januar 2000 Ortszeit entspricht und dass die Revision der Anzahl der Sekunden seit Mitternacht Ortszeit entspricht, geteilt durch 2.
Siehe Community-Inhalt, automatische Build- und Revisionsnummern
zB AssemblyInfo.cs
SampleCode.cs
quelle
TimeZone.CurrentTimeZone.IsDaylightSavingTime(buildDateTime) == true
IMAGE_FILE_HEADER::TimeDateStamp
Feld auf eine Zufallszahl gesetzt und ist kein Zeitstempel mehr.Fügen Sie der Befehlszeile für vorgefertigte Ereignisse Folgendes hinzu:
Fügen Sie diese Datei als Ressource hinzu. Jetzt haben Sie die Zeichenfolge 'BuildDate' in Ihren Ressourcen.
Nachdem ich die Datei in die Ressource eingefügt hatte (als öffentliche Textdatei), habe ich über darauf zugegriffen
Informationen zum Erstellen von Ressourcen finden Sie unter Erstellen und Verwenden von Ressourcen in .NET .
quelle
Ein Ansatz, von dem ich erstaunt bin, dass noch niemand ihn erwähnt hat, ist die Verwendung von T4-Textvorlagen zur Codegenerierung.
Vorteile:
Nachteile:
quelle
Constants.CompilationTimestampUtc
. Wenn VS keine C # -Datei mit der Klasse generiert, müssen Sie herausfinden, wie Sie dies erreichen können. Die Antwort hängt jedoch (zumindest) von der Version von VS und dem Typ der csproj-Datei ab zu viele Details für diesen Beitrag.In Bezug auf die Technik zum Abrufen von Build-Datums- / Versionsinformationen aus den Bytes eines Assembly-PE-Headers hat Microsoft die Standard-Build-Parameter ab Visual Studio 15.4 geändert. Die neue Standardeinstellung umfasst die deterministische Kompilierung, wodurch ein gültiger Zeitstempel und automatisch inkrementierte Versionsnummern der Vergangenheit angehören. Das Zeitstempelfeld ist immer noch vorhanden, wird jedoch mit einem permanenten Wert gefüllt, der ein Hash von irgendetwas ist, aber keinen Hinweis auf die Erstellungszeit.
Einige detaillierte Hintergrundinformationen hier
Für diejenigen, die einen nützlichen Zeitstempel vor der deterministischen Kompilierung priorisieren, gibt es eine Möglichkeit, den neuen Standard zu überschreiben. Sie können ein Tag wie folgt in die .csproj-Datei der interessierenden Assembly aufnehmen:
Update: Ich unterstütze die in einer anderen Antwort hier beschriebene T4-Textvorlagenlösung. Ich habe es verwendet, um mein Problem sauber zu lösen, ohne den Vorteil der deterministischen Kompilierung zu verlieren. Eine Warnung ist, dass Visual Studio den T4-Compiler nur ausführt, wenn die .tt-Datei gespeichert wird, nicht zur Erstellungszeit. Dies kann unangenehm sein, wenn Sie das CS-Ergebnis von der Quellcodeverwaltung ausschließen (da Sie erwarten, dass es generiert wird) und ein anderer Entwickler den Code auscheckt. Ohne erneutes Speichern verfügen sie nicht über die CS-Datei. Auf nuget gibt es ein Paket (ich glaube AutoT4), das die T4-Kompilierung zu einem Teil jedes Builds macht. Ich habe die Lösung für dieses Problem während der Produktionsbereitstellung noch nicht konfrontiert, aber ich erwarte, dass etwas Ähnliches es richtig macht.
quelle
Ich bin nur ein C # -Neuling, daher klingt meine Antwort vielleicht albern - ich zeige das Erstellungsdatum ab dem Datum an, an dem die ausführbare Datei zuletzt geschrieben wurde:
Ich habe versucht, die File.GetCreationTime-Methode zu verwenden, habe aber seltsame Ergebnisse erzielt: Das Datum aus dem Befehl war 2012-05-29, aber das Datum aus dem Fenster-Explorer zeigte 2012-05-23 an. Nachdem ich nach dieser Diskrepanz gesucht hatte, stellte ich fest, dass die Datei wahrscheinlich am 23.05.2012 erstellt wurde (wie vom Windows Explorer angezeigt), aber am 29.05.2012 in den aktuellen Ordner kopiert wurde (wie vom Befehl File.GetCreationTime angezeigt) Um auf der sicheren Seite zu sein, verwende ich den Befehl File.GetLastWriteTime.
Zalek
quelle
LastWriteTime
, da dies genau die Zeit widerspiegelt, zu der die ausführbare Datei tatsächlich aktualisiert wurde.Viele gute Antworten hier, aber ich habe das Gefühl, dass ich aufgrund der Einfachheit, der Leistung (im Vergleich zu ressourcenbezogenen Lösungen) plattformübergreifend (funktioniert auch mit Net Core) und der Vermeidung von Tools von Drittanbietern meine eigenen hinzufügen kann. Fügen Sie einfach dieses msbuild-Ziel zum csproj hinzu.
und jetzt hast du
Builtin.CompileTime
odernew DateTime(Builtin.CompileTime, DateTimeKind.Utc)
wenn du es so brauchst.ReSharper wird es nicht mögen. Sie können ihn ignorieren oder dem Projekt auch eine Teilklasse hinzufügen, aber es funktioniert trotzdem.
quelle
Builtin.CompileTime
von einer Rasiermesseransicht aus zugreife .BeforeTargets="RazorCoreCompile"
aber nur, während dies im selben Projekt istFür .NET Core-Projekte habe ich die Antwort von Postlagerkarte angepasst, um das Feld für das Assembly-Copyright mit dem Erstellungsdatum zu aktualisieren.
Bearbeiten Sie csproj direkt
Folgendes kann direkt zum ersten
PropertyGroup
im csproj hinzugefügt werden:Alternative: Visual Studio-Projekteigenschaften
Oder fügen Sie den inneren Ausdruck direkt in das Feld Copyright im Abschnitt Package der Projekteigenschaften in Visual Studio ein:
Dies kann etwas verwirrend sein, da Visual Studio den Ausdruck auswertet und den aktuellen Wert im Fenster anzeigt, aber auch die Projektdatei hinter den Kulissen entsprechend aktualisiert.
Lösungsweit über Directory.Build.props
Sie können das obige
<Copyright>
Element in eineDirectory.Build.props
Datei in Ihrem Lösungsstamm einfügen und es automatisch auf alle Projekte im Verzeichnis anwenden lassen, vorausgesetzt, jedes Projekt liefert nicht seinen eigenen Copyright-Wert.Directory.Build.props: Passen Sie Ihren Build an
Ausgabe
Der Beispielausdruck gibt Ihnen ein Copyright wie folgt:
Abruf
Sie können die Copyright-Informationen in den Dateieigenschaften in Windows anzeigen oder zur Laufzeit abrufen:
quelle
Die obige Methode kann für bereits im Prozess geladene Assemblys optimiert werden, indem das Image der Datei im Speicher verwendet wird (im Gegensatz zum erneuten Lesen aus dem Speicher):
quelle
Für alle, die die Kompilierungszeit in Windows 8 / Windows Phone 8 benötigen:
Für alle, die die Kompilierungszeit in Windows Phone 7 benötigen:
ANMERKUNG: In allen Fällen werden Sie in einer Sandbox ausgeführt, sodass Sie nur die Kompilierungszeit von Assemblys abrufen können, die Sie mit Ihrer App bereitstellen. (dh dies funktioniert bei nichts im GAC).
quelle
var assembly = typeof (AnyTypeInYourAssembly).GetTypeInfo().Assembly;
Im Jahr 2018 funktionieren einige der oben genannten Lösungen nicht mehr oder nicht mit .NET Core.
Ich verwende den folgenden Ansatz, der einfach ist und für mein .NET Core 2.0-Projekt funktioniert.
Fügen Sie Ihrer .csproj in der PropertyGroup Folgendes hinzu:
Dies definiert eine PropertyFunction die Sie in Ihrem Pre-Build-Befehl zugreifen können.
Ihr Pre-Build sieht so aus
Setzen Sie die Eigenschaft der Datei BuildTimeStamp.txt auf Eingebettete Ressource.
Jetzt können Sie den Zeitstempel so lesen
quelle
"$(ProjectDir)BuildTimeStamp.txt"
), da es sonst unterbrochen wird, wenn die Ordnernamen Leerzeichen enthalten.$([System.DateTime]::Now.tostring("MM/dd/yyyy HH:mm:ss"))
statt$([System.DateTime]::Now)
Die hier nicht diskutierte Option besteht darin, Ihre eigenen Daten in AssemblyInfo.cs einzufügen. Das Feld "AssemblyInformationalVersion" erscheint angemessen. Wir haben einige Projekte, in denen wir etwas Ähnliches als Build-Schritt ausgeführt haben (mit dem bin ich jedoch nicht ganz zufrieden) So funktioniert das, also will ich nicht wirklich reproduzieren, was wir haben.
Es gibt einen Artikel zu diesem Thema auf Codeproject: http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspx
quelle
Ich brauchte eine universelle Lösung, die mit einem NETStandard-Projekt auf jeder Plattform (iOS, Android und Windows) funktioniert. Um dies zu erreichen, habe ich beschlossen, automatisch eine CS-Datei über ein PowerShell-Skript zu generieren. Hier ist das PowerShell-Skript:
Speichern Sie die PowerScript-Datei als GenBuildDate.ps1 und fügen Sie sie Ihrem Projekt hinzu. Fügen Sie abschließend Ihrem Pre-Build-Ereignis die folgende Zeile hinzu:
Stellen Sie sicher, dass BuildDate.cs in Ihrem Projekt enthalten ist. Funktioniert wie ein Champion auf jedem Betriebssystem!
quelle
Ich mache einfach:
quelle
Sie können dieses Projekt verwenden: https://github.com/dwcullop/BuildInfo
Es nutzt T4, um den Zeitstempel für das Erstellungsdatum zu automatisieren. Es gibt mehrere Versionen (verschiedene Zweige), darunter eine, die Ihnen den Git-Hash des aktuell ausgecheckten Zweigs gibt, wenn Sie sich für solche Dinge interessieren.
Offenlegung: Ich habe das Modul geschrieben.
quelle
Ein anderer, PCL-freundlicher Ansatz wäre die Verwendung einer MSBuild-Inline-Task, um die Erstellungszeit durch eine Zeichenfolge zu ersetzen, die von einer Eigenschaft in der App zurückgegeben wird. Wir verwenden diesen Ansatz erfolgreich in einer App mit Xamarin.Forms-, Xamarin.Android- und Xamarin.iOS-Projekten.
BEARBEITEN:
Vereinfacht durch Verschieben der gesamten Logik in die
SetBuildDate.targets
Datei und Verwenden vonRegex
anstelle eines einfachen String-Ersetzens, sodass die Datei von jedem Build ohne "Zurücksetzen" geändert werden kann.Die MSBuild-Inline-Taskdefinition (gespeichert in einer SetBuildDate.targets-Datei, die für dieses Beispiel lokal im Xamarin.Forms-Projekt gespeichert ist):
Aufrufen der obigen Inline-Aufgabe in der Datei Xamarin.Forms csproj im Ziel BeforeBuild:
Die
FilePath
Eigenschaft wirdBuildMetadata.cs
im Xamarin.Forms-Projekt auf eine Datei festgelegt, die eine einfache Klasse mit einer Zeichenfolgeeigenschaft enthältBuildDate
, in die die Erstellungszeit eingesetzt wird:Fügen Sie diese Datei
BuildMetadata.cs
zum Projekt hinzu. Es wird von jedem Build geändert, jedoch auf eine Weise, die wiederholte Builds (wiederholtes Ersetzen) ermöglicht, sodass Sie es nach Bedarf in die Quellcodeverwaltung aufnehmen oder weglassen können.quelle
Sie können ein Projektereignis nach dem Erstellen verwenden, um eine Textdatei mit der aktuellen Datums- und Uhrzeitangabe in Ihr Zielverzeichnis zu schreiben. Sie können den Wert dann zur Laufzeit lesen. Es ist ein bisschen hacky, aber es sollte funktionieren.
quelle
Ich bin mir nicht sicher, aber vielleicht hilft der Build Incrementer .
quelle
Ein kleines Update zur "New Way" -Antwort von Jhon.
Sie müssen den Pfad erstellen, anstatt die CodeBase-Zeichenfolge zu verwenden, wenn Sie mit ASP.NET/MVC arbeiten
quelle
Sie können einen zusätzlichen Schritt im Erstellungsprozess starten, bei dem ein Datumsstempel in eine Datei geschrieben wird, die dann angezeigt werden kann.
Sehen Sie sich auf der Registerkarte Projekteigenschaften die Registerkarte Build-Ereignisse an. Es besteht die Möglichkeit, einen Befehl vor oder nach dem Erstellen auszuführen.
quelle
Ich habe Abdurrahims Vorschlag verwendet. Es schien jedoch ein seltsames Zeitformat zu geben und fügte auch die Abkürzung für den Tag als Teil des Erstellungsdatums hinzu. Beispiel: So 24.12.2017 13: 21: 05.43 Uhr. Ich brauchte nur das Datum, also musste ich den Rest mit Teilzeichenfolgen entfernen.
Nachdem ich das
echo %date% %time% > "$(ProjectDir)\Resources\BuildDate.txt"
zum Pre-Build-Ereignis hinzugefügt habe , habe ich Folgendes getan:Die gute Nachricht hier ist, dass es funktioniert hat.
quelle
Wenn dies eine Windows-App ist, können Sie einfach den ausführbaren Pfad der Anwendung verwenden: new System.IO.FileInfo (Application.ExecutablePath) .LastWriteTime.ToString ("yyyy.MM.dd")
quelle
es könnte sein
Assembly execAssembly = Assembly.GetExecutingAssembly(); var creationTime = new FileInfo(execAssembly.Location).CreationTime; // "2019-09-08T14:29:12.2286642-04:00"
quelle