Obecnie mam aplikację wyświetlającą numer kompilacji w oknie tytułu. To dobrze, ale nic nie znaczy dla większości użytkowników, którzy chcą wiedzieć, czy mają najnowszą kompilację - zwykle nazywają ją „ostatnim czwartkiem”, a nie kompilacją 1.0.8.4321.
Zamiast tego planuje się tam podać datę kompilacji - na przykład „Aplikacja zbudowana 21/10/2009”.
Usiłuję znaleźć programowy sposób na wyciągnięcie daty kompilacji jako ciągu tekstowego do użycia w ten sposób.
Do numeru kompilacji użyłem:
Assembly.GetExecutingAssembly().GetName().Version.ToString()
po zdefiniowaniu, jak się pojawiły.
Chciałbym coś takiego na datę kompilacji (i czas, dla punktów bonusowych).
Wskaźniki tutaj bardzo doceniane (w razie potrzeby usprawiedliwiaj grę słów) lub bardziej odpowiednie rozwiązania ...
c#
date
time
compilation
Mark Mayo
źródło
źródło
Odpowiedzi:
Jeff Atwood miał kilka rzeczy do powiedzenia na temat tego problemu w Określanie daty kompilacji na własnej skórze .
Okazuje się, że najbardziej niezawodną metodą jest pobranie znacznika czasowego linkera z nagłówka PE osadzonego w pliku wykonywalnym - trochę kodu C # (autorstwa Joe Spivey'a) z komentarzy do artykułu Jeffa:
Przykład użycia:
AKTUALIZACJA: Metoda działała dla .Net Core 1.0, ale przestała działać po wydaniu .Net Core 1.1 (daje losowe lata w przedziale 1900-2020)
źródło
.AddHours()
jest raczej hackerska i (myślę) nie weźmie pod uwagę DST. Jeśli chcesz w czasie lokalnym,dt.ToLocalTime();
zamiast tego powinieneś użyć odkurzacza . Środkową część można również znacznie uprościćusing()
blokiem.Dodaj poniżej, aby wiersza polecenia zdarzenia przed kompilacją:
Dodaj ten plik jako zasób, teraz masz ciąg „BuildDate” w swoich zasobach.
Aby utworzyć zasoby, zobacz Jak tworzyć i wykorzystywać zasoby w .NET .
źródło
Droga
Jak wskazał @ c00000fd w komentarzach . Microsoft to zmienia. I chociaż wiele osób nie korzysta z najnowszej wersji swojego kompilatora, podejrzewam, że ta zmiana czyni to podejście niewątpliwie złym. I chociaż jest to zabawne ćwiczenie, polecam ludziom, aby po prostu osadzili datę kompilacji w swoim pliku binarnym za pomocą wszelkich innych niezbędnych środków, jeśli ważne jest śledzenie daty kompilacji samego pliku binarnego.
Można to zrobić za pomocą trywialnego generowania kodu, który prawdopodobnie jest już pierwszym krokiem w skrypcie kompilacji. To oraz fakt, że narzędzia ALM / Build / DevOps bardzo w tym pomagają i powinny być preferowane w stosunku do wszystkiego innego.
Pozostałą część tej odpowiedzi pozostawiam tutaj wyłącznie do celów historycznych.
Nowy sposób
Zmieniłem zdanie na ten temat i obecnie używam tej sztuczki, aby uzyskać prawidłową datę kompilacji.
Po staremu
Jak generujesz liczby kompilacji? Visual Studio (lub kompilator C #) faktycznie zapewnia automatyczne numery kompilacji i wersji, jeśli zmienisz atrybut AssemblyVersion na np
1.0.*
Stanie się tak, że kompilacja będzie równa liczbie dni od 1 stycznia 2000 czasu lokalnego, a korekta będzie równa liczbie sekund od północy czasu lokalnego, podzielonej przez 2.
zobacz zawartość społeczności, automatyczne kompilacje i numery wersji
np. AssemblyInfo.cs
SampleCode.cs
źródło
TimeZone.CurrentTimeZone.IsDaylightSavingTime(buildDateTime) == true
IMAGE_FILE_HEADER::TimeDateStamp
pole jest ustawione na liczbę losową i nie jest już czas-pieczęć.Dodaj poniżej, aby wiersza polecenia zdarzenia przed kompilacją:
Dodaj ten plik jako zasób, teraz masz ciąg „BuildDate” w swoich zasobach.
Po wstawieniu pliku do zasobu (jako publicznego pliku tekstowego) uzyskałem do niego dostęp za pośrednictwem
Aby utworzyć zasoby, zobacz Jak tworzyć i wykorzystywać zasoby w .NET .
źródło
Jednym z podejść, które mnie zadziwia, o którym nikt jeszcze nie wspomniał, jest użycie szablonów tekstowych T4 do generowania kodu.
Plusy:
Cons:
źródło
Constants.CompilationTimestampUtc
. Jeśli VS nie generuje pliku C # z klasą, musisz dowiedzieć się, jak to zrobić, ale odpowiedź zależy (przynajmniej) od wersji VS i typu pliku csproj, więc jest to za dużo szczegółów dla tego postu.Jeśli chodzi o technikę pobierania informacji o dacie kompilacji / wersji z bajtów nagłówka PE zestawu, Microsoft zmienił domyślne parametry kompilacji, zaczynając od Visual Studio 15.4. Nowe ustawienie domyślne obejmuje kompilację deterministyczną, dzięki czemu ważny znacznik czasu i automatycznie zwiększane numery wersji należą już do przeszłości. Pole znacznika czasu jest nadal obecne, ale zostaje wypełnione stałą wartością, która jest skrótem czegoś lub innego, ale nie wskazuje na czas kompilacji.
Kilka szczegółowych informacji tutaj
Dla tych, którzy nadają priorytet użytecznemu znacznikowi czasu przed kompilacją deterministyczną, istnieje sposób na zastąpienie nowego ustawienia domyślnego. Możesz dołączyć znacznik do pliku .csproj zespołu będącego przedmiotem zainteresowania w następujący sposób:
Aktualizacja: Popieram rozwiązanie szablonu tekstowego T4 opisane w innej odpowiedzi tutaj. Użyłem go do czystego rozwiązania problemu, nie tracąc korzyści z kompilacji deterministycznej. Jedną ostrożnością jest to, że Visual Studio uruchamia kompilator T4 tylko wtedy, gdy plik .tt jest zapisywany, a nie podczas kompilacji. Może to być niewygodne, jeśli wykluczysz wynik .cs z kontroli źródła (ponieważ spodziewasz się, że zostanie wygenerowany), a inny programista sprawdzi kod. Bez ponownego zapisywania nie będą mieli pliku .cs. W nugecie znajduje się pakiet (myślę, że nazywa się AutoT4), który sprawia, że kompilacja T4 jest częścią każdej kompilacji. Nie spotkałem się jeszcze z rozwiązaniem tego problemu podczas wdrażania produkcyjnego, ale spodziewam się czegoś podobnego, aby to naprawić.
źródło
Jestem tylko nowicjuszem w C #, więc może moja odpowiedź brzmi głupio - wyświetlam datę kompilacji od daty ostatniego zapisania pliku wykonywalnego:
Próbowałem użyć metody File.GetCreationTime, ale otrzymałem dziwne wyniki: data z polecenia to 29.05.2012, ale data z Eksploratora Windows pokazała 23.05.2012. Po wyszukaniu tej rozbieżności odkryłem, że plik prawdopodobnie został utworzony w dniu 23.05.2012 r. (Jak pokazano w Eksploratorze Windows), ale został skopiowany do bieżącego folderu w dniu 29.05.2012 r. (Jak pokazano w poleceniu File.GetCreationTime) - więc dla bezpieczeństwa Używam polecenia File.GetLastWriteTime.
Zalek
źródło
LastWriteTime
, ponieważ dokładnie odzwierciedla on czas faktycznej aktualizacji pliku wykonywalnego.Wiele świetnych odpowiedzi tutaj, ale wydaje mi się, że mogę dodać własne ze względu na prostotę, wydajność (w porównaniu z rozwiązaniami związanymi z zasobami) między platformami (działa również z Net Core) i unikanie jakiegokolwiek narzędzia innej firmy. Wystarczy dodać ten cel msbuild do csproj.
a teraz masz
Builtin.CompileTime
lubnew DateTime(Builtin.CompileTime, DateTimeKind.Utc)
jeśli potrzebujesz tego w ten sposób.ReSharper się nie spodoba. Możesz go zignorować lub dodać częściową klasę do projektu, ale i tak działa.
źródło
Builtin.CompileTime
z widoku Razor.BeforeTargets="RazorCoreCompile"
ale tylko wtedy, gdy jest to ten sam projektW przypadku projektów .NET Core dostosowałem odpowiedź Postlagerkarte, aby zaktualizować pole Prawa autorskie zestawu o datę kompilacji.
Bezpośrednio edytuj csproj
Następujące można dodać bezpośrednio do pierwszego
PropertyGroup
w csproj:Alternatywa: właściwości projektu Visual Studio
Lub wklej wyrażenie wewnętrzne bezpośrednio w polu Copyright w sekcji Package właściwości projektu w Visual Studio:
Może to być nieco mylące, ponieważ Visual Studio oceni wyrażenie i wyświetli bieżącą wartość w oknie, ale odpowiednio zaktualizuje plik projektu za scenami.
W całym rozwiązaniu za pośrednictwem Directory.Build.props
Możesz
<Copyright>
umieścić element powyżej wDirectory.Build.props
pliku w katalogu głównym rozwiązania i automatycznie zastosować go do wszystkich projektów w katalogu, zakładając, że każdy projekt nie podaje własnej wartości autorskiej.Directory.Build.props: Dostosuj swoją kompilację
Wynik
Przykładowe wyrażenie da ci prawa autorskie takie jak to:
Wyszukiwanie
Możesz wyświetlić informacje o prawach autorskich z właściwości pliku w systemie Windows lub pobrać je w czasie wykonywania:
źródło
Powyższą metodę można ulepszyć dla zestawów już załadowanych w procesie , używając obrazu pliku w pamięci (w przeciwieństwie do ponownego odczytu go z pamięci):
źródło
Dla każdego, kto musi uzyskać czas kompilacji w systemie Windows 8 / Windows Phone 8:
Dla każdego, kto musi uzyskać czas kompilacji w Windows Phone 7:
UWAGA: We wszystkich przypadkach korzystasz z piaskownicy, więc będziesz mógł uzyskać tylko czas kompilacji zestawów, które wdrażasz z aplikacją. (tzn. to nie zadziała na niczym w GAC).
źródło
var assembly = typeof (AnyTypeInYourAssembly).GetTypeInfo().Assembly;
W 2018 r. Niektóre z powyższych rozwiązań już nie działają lub nie działają z platformą .NET Core.
Korzystam z następującego podejścia, które jest proste i działa w moim projekcie .NET Core 2.0.
Dodaj następujące elementy do .csproj wewnątrz PropertyGroup:
Definiuje to funkcję PropertyFunction, do której można uzyskać dostęp w poleceniu przed kompilacją.
Twoja wersja wstępna wygląda tak
Ustaw właściwość BuildTimeStamp.txt na Zasób osadzony.
Teraz możesz odczytać znacznik czasu w ten sposób
źródło
"$(ProjectDir)BuildTimeStamp.txt"
), Bo pęknie, gdy w nazwach folderów będzie spacja.$([System.DateTime]::Now.tostring("MM/dd/yyyy HH:mm:ss"))
zamiast$([System.DateTime]::Now)
Nie omawianą tutaj opcją jest wstawienie własnych danych do AssemblyInfo.cs, pole „AssemblyInformationalVersion” wydaje się odpowiednie - mamy kilka projektów, w których robiliśmy coś podobnego jak krok kompilacji (jednak nie jestem do końca zadowolony z sposób, który działa, więc tak naprawdę nie chcę reprodukować tego, co mamy).
Istnieje artykuł na ten temat na temat projektu kodowego: http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspx
źródło
Potrzebowałem uniwersalnego rozwiązania, które działałoby z projektem NETStandard na dowolnej platformie (iOS, Android i Windows). Aby to osiągnąć, postanowiłem automatycznie wygenerować plik CS za pomocą skryptu PowerShell. Oto skrypt PowerShell:
Zapisz plik PowerScript jako GenBuildDate.ps1 i dodaj go do swojego projektu. Na koniec dodaj następujący wiersz do wydarzenia przed kompilacją:
Upewnij się, że plik BuildDate.cs jest uwzględniony w projekcie. Działa jak mistrz na każdym systemie operacyjnym!
źródło
Po prostu robię:
źródło
Możesz użyć tego projektu: https://github.com/dwcullop/BuildInfo
Wykorzystuje T4 do automatyzacji znacznika czasu kompilacji. Istnieje kilka wersji (różne gałęzie), w tym jedna, która daje Git Hash aktualnie wyewidencjonowanej gałęzi, jeśli lubisz takie rzeczy.
Ujawnienie: Napisałem moduł.
źródło
Innym podejściem przyjaznym dla PCL byłoby użycie wbudowanego zadania MSBuild do zastąpienia czasu kompilacji ciągiem zwracanym przez właściwość w aplikacji. Z powodzeniem stosujemy to podejście w aplikacji, która ma projekty Xamarin.Forms, Xamarin.Android i Xamarin.iOS.
EDYTOWAĆ:
Uproszczone przez przeniesienie całej logiki do
SetBuildDate.targets
pliku i użycieRegex
zamiast zwykłego ciągu znaków zamień, aby plik mógł być modyfikowany przez każdą kompilację bez „resetowania”.Definicja wbudowanego zadania MSBuild (zapisana w lokalnym pliku SetBuildDate.targets w projekcie Xamarin.Forms w tym przykładzie):
Wywoływanie powyższego zadania wbudowanego w pliku csproj Xamarin.Forms w docelowym BeforeBuild:
FilePath
Właściwość jest ustawiona doBuildMetadata.cs
pliku w projekcie Xamarin.Forms który zawiera prostą klasę z właściwości StringBuildDate
, w których czas budowy zostanie podstawiony:Dodaj ten plik
BuildMetadata.cs
do projektu. Będzie modyfikowany przy każdej kompilacji, ale w sposób, który pozwala na powtarzane kompilacje (powtarzane zamiany), więc możesz uwzględnić lub pominąć go w kontroli źródła według potrzeb.źródło
Możesz użyć zdarzenia po kompilacji projektu, aby zapisać plik tekstowy do katalogu docelowego z bieżącą datetime. Następnie możesz odczytać wartość w czasie wykonywania. Jest trochę zuchwały, ale powinien działać.
źródło
Nie jestem pewien, ale być może Build Incrementer pomaga.
źródło
Mała aktualizacja odpowiedzi „New Way” od Jhon.
Podczas pracy z programem ASP.NET/MVC musisz zbudować ścieżkę zamiast ciągów CodeBase
źródło
Możesz uruchomić dodatkowy krok w procesie kompilacji, który zapisuje znacznik daty do pliku, który można następnie wyświetlić.
Na karcie właściwości projektów spójrz na kartę zdarzeń kompilacji. Istnieje opcja wykonania polecenia przed kompilacją lub po kompilacji.
źródło
Skorzystałem z sugestii Abdurrahima. Wydawało się jednak, że podało dziwny format czasu, a także dodało skrót dnia jako część daty kompilacji; przykład: nie 12.12.2017 13: 21: 05.43. Potrzebowałem tylko daty, więc musiałem wyeliminować resztę za pomocą podciągów.
Po dodaniu
echo %date% %time% > "$(ProjectDir)\Resources\BuildDate.txt"
zdarzenia do wersji wstępnej po prostu wykonałem następujące czynności:Dobrą wiadomością jest to, że działało.
źródło
Jeśli jest to aplikacja Windows, możesz po prostu użyć ścieżki wykonywalnej aplikacji: new System.IO.FileInfo (Application.ExecutablePath) .LastWriteTime.ToString („rrrr.MM.dd”)
źródło
mogłoby być
Assembly execAssembly = Assembly.GetExecutingAssembly(); var creationTime = new FileInfo(execAssembly.Location).CreationTime; // "2019-09-08T14:29:12.2286642-04:00"
źródło