Wyświetlanie daty budowy

Obecnie mam aplikację wyświetlającą numer kompilacji w oknie tytuł. To dobrze i dobrze, ale to nic nie znaczy dla większości użytkowników, którzy chcą wiedzieć, czy mają najnowszą kompilację - zwykle nazywają ją "zeszłego czwartku", a nie build 1.0.8.4321.

Plan polega na umieszczeniu tam daty budowy - tak na przykład "App built on 21/10/2009".

Staram się znaleźć programowy sposób na wyciągnięcie daty kompilacji jako ciąg tekstowy do użycia jak to.

Dla numeru budowy użyłem:

Assembly.GetExecutingAssembly().GetName().Version.ToString()

Po określeniu, jak powstały.

Chciałbym coś takiego Dla daty kompilacji (i czasu, dla punktów bonusowych).

Wskaźniki tutaj bardzo doceniane (wymówka kalambur, jeśli to właściwe), lub schludniejsze rozwiązania...

Author: Luke Girvin, 2009-10-21

22 answers

Jeff Atwood miał kilka rzeczy do powiedzenia na ten temat w ustalaniu daty budowy w trudny sposób .

Najbardziej niezawodną metodą okazuje się pobranie znacznika czasu linkera z nagłówka PE osadzonego w pliku wykonywalnym -- jakiś kod C# (autorstwa Joe Spivey) dla tego z komentarzy do artykułu Jeffa:

public static DateTime GetLinkerTime(this Assembly assembly, TimeZoneInfo target = null)
{
    var filePath = assembly.Location;
    const int c_PeHeaderOffset = 60;
    const int c_LinkerTimestampOffset = 8;

    var buffer = new byte[2048];

    using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        stream.Read(buffer, 0, 2048);

    var offset = BitConverter.ToInt32(buffer, c_PeHeaderOffset);
    var secondsSince1970 = BitConverter.ToInt32(buffer, offset + c_LinkerTimestampOffset);
    var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

    var linkTimeUtc = epoch.AddSeconds(secondsSince1970);

    var tz = target ?? TimeZoneInfo.Local;
    var localTime = TimeZoneInfo.ConvertTimeFromUtc(linkTimeUtc, tz);

    return localTime;
}

Przykład użycia:

var linkTimeLocal = Assembly.GetExecutingAssembly().GetLinkerTime();

Aktualizacja: metoda działała dla. Net Core 1.0, ale przestała działać po. Net Core 1.1 wydanie (podaje losowe lata w przedziale 1900-2020)

 338
Author: mdb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-29 07:16:54

The new way

Zmieniłem zdanie na ten temat i obecnie używam tej sztuczki, aby uzyskać poprawną datę budowy.

#region Gets the build date and time (by reading the COFF header)

// http://msdn.microsoft.com/en-us/library/ms680313

struct _IMAGE_FILE_HEADER
{
    public ushort Machine;
    public ushort NumberOfSections;
    public uint TimeDateStamp;
    public uint PointerToSymbolTable;
    public uint NumberOfSymbols;
    public ushort SizeOfOptionalHeader;
    public ushort Characteristics;
};

static DateTime GetBuildDateTime(Assembly assembly)
{
    var path = assembly.GetName().CodeBase;
    if (File.Exists(path))
    {
        var buffer = new byte[Math.Max(Marshal.SizeOf(typeof(_IMAGE_FILE_HEADER)), 4)];
        using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
        {
            fileStream.Position = 0x3C;
            fileStream.Read(buffer, 0, 4);
            fileStream.Position = BitConverter.ToUInt32(buffer, 0); // COFF header offset
            fileStream.Read(buffer, 0, 4); // "PE\0\0"
            fileStream.Read(buffer, 0, buffer.Length);
        }
        var pinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
        try
        {
            var coffHeader = (_IMAGE_FILE_HEADER)Marshal.PtrToStructure(pinnedBuffer.AddrOfPinnedObject(), typeof(_IMAGE_FILE_HEADER));

            return TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1) + new TimeSpan(coffHeader.TimeDateStamp * TimeSpan.TicksPerSecond));
        }
        finally
        {
            pinnedBuffer.Free();
        }
    }
    return new DateTime();
}

#endregion

The old way

Jak generować liczby kompilacji? Visual Studio (lub kompilator C#) faktycznie dostarcza automatyczne numery kompilacji i wersji, jeśli zmienisz atrybut AssemblyVersion na np. 1.0.*

Co się stanie, to to, że budowa będzie równa liczbie dni od 1 stycznia 2000 czasu lokalnego, a dla rewizji być równa liczbie sekund od północy czasu lokalnego, podzielonej przez 2.

Zobacz zawartość społeczności, automatyczne numery kompilacji i rewizji

Np. AssemblyInfo.cs

[assembly: AssemblyVersion("1.0.*")] // important: use wildcard for build and revision numbers!

SampleCode.cs

var version = Assembly.GetEntryAssembly().GetName().Version;
var buildDateTime = new DateTime(2000, 1, 1).Add(new TimeSpan(
TimeSpan.TicksPerDay * version.Build + // days since 1 January 2000
TimeSpan.TicksPerSecond * 2 * version.Revision)); // seconds since midnight, (multiply by 2 to get original)
 82
Author: John Leidegren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-29 12:35:47

Dodaj poniżej do wiersza poleceń pre-build event:

echo %date% %time% > "$(ProjectDir)\Resources\BuildDate.txt"

Dodaj ten plik jako zasób, teraz masz ciąg' BuildDate ' w swoich Zasobach.

Aby utworzyć zasoby, zobacz Jak tworzyć i używać zasobów w. Net .
 79
Author: Abdurrahim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:17

Dodaj poniżej do wiersza poleceń pre-build event:

echo %date% %time% > "$(ProjectDir)\Resources\BuildDate.txt"

Dodaj ten plik jako zasób, teraz masz ciąg' BuildDate ' w swoich Zasobach.

Po włożeniu pliku do zasobu (jako publiczny plik tekstowy), uzyskałem do niego dostęp poprzez

string strCompTime = Properties.Resources.BuildDate;
Aby utworzyć zasoby, zobacz Jak tworzyć i używać zasobów w. NET.
 35
Author: brewmanz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:43

Jedno podejście, o którym dziwi mnie, że nikt jeszcze nie wspomniał, to użycie szablonów tekstowych T4 do generowania kodu.

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System" #>
<#@ output extension=".g.cs" #>
namespace Foo.Bar
{
    public static partial class Constants
    {
        public static DateTime CompilationTimestampUtc { get { return new DateTime(<# Write(DateTime.UtcNow.Ticks); #>L, DateTimeKind.Utc); } }
    }
}

Plusy:

  • Locale-independent
  • pozwala na znacznie więcej niż tylko czas kompilacji

Wady:

 13
Author: Peter Taylor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:43

Jestem po prostu C# newbie, więc może moja odpowiedź brzmi głupio-wyświetlam datę kompilacji od daty ostatniego zapisu pliku wykonywalnego:

string w_file = "MyProgram.exe"; 
string w_directory = Directory.GetCurrentDirectory();

DateTime c3 =  File.GetLastWriteTime(System.IO.Path.Combine(w_directory, w_file));
RTB_info.AppendText("Program created at: " + c3.ToString());
Próbowałem użyć pliku.Metoda GetCreationTime ale ma dziwne wyniki: Data z polecenia była 2012-05-29, ale Data z Eksploratora okien pokazała 2012-05-23. Po wyszukaniu tej rozbieżności okazało się, że plik został prawdopodobnie utworzony w dniu 2012-05-23 (jak pokazuje Eksplorator Windows), ale skopiowany do bieżącego folderu w dniu 2012-05-29 (jak pokazano w pliku.GetCreationTime command) - tak aby być po bezpiecznej stronie używam pliku.Polecenie GetLastWriteTime.

Zalek

 12
Author: Zalek Bloom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-15 15:00:02

Nie omawiana tutaj opcja to 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 budowania(jednak nie jestem do końca zadowolony ze sposobu, w jaki to działa, więc tak naprawdę nie chcę powielać tego, co mamy).

Jest artykuł na ten temat na codeproject: http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspx

 8
Author: Murph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-21 14:08:43

Dla każdego, kto potrzebuje czasu kompilacji w Windows 8 / Windows Phone 8:

    public static async Task<DateTimeOffset?> RetrieveLinkerTimestamp(Assembly assembly)
    {
        var pkg = Windows.ApplicationModel.Package.Current;
        if (null == pkg)
        {
            return null;
        }

        var assemblyFile = await pkg.InstalledLocation.GetFileAsync(assembly.ManifestModule.Name);
        if (null == assemblyFile)
        {
            return null;
        }

        using (var stream = await assemblyFile.OpenSequentialReadAsync())
        {
            using (var reader = new DataReader(stream))
            {
                const int PeHeaderOffset = 60;
                const int LinkerTimestampOffset = 8;

                //read first 2048 bytes from the assembly file.
                byte[] b = new byte[2048];
                await reader.LoadAsync((uint)b.Length);
                reader.ReadBytes(b);
                reader.DetachStream();

                //get the pe header offset
                int i = System.BitConverter.ToInt32(b, PeHeaderOffset);

                //read the linker timestamp from the PE header
                int secondsSince1970 = System.BitConverter.ToInt32(b, i + LinkerTimestampOffset);

                var dt = new DateTimeOffset(1970, 1, 1, 0, 0, 0, DateTimeOffset.Now.Offset) + DateTimeOffset.Now.Offset;
                return dt.AddSeconds(secondsSince1970);
            }
        }
    }

Dla każdego, kto potrzebuje czasu kompilacji w Windows Phone 7:

    public static async Task<DateTimeOffset?> RetrieveLinkerTimestampAsync(Assembly assembly)
    {
        const int PeHeaderOffset = 60;
        const int LinkerTimestampOffset = 8;            
        byte[] b = new byte[2048];

        try
        {
            var rs = Application.GetResourceStream(new Uri(assembly.ManifestModule.Name, UriKind.Relative));
            using (var s = rs.Stream)
            {
                var asyncResult = s.BeginRead(b, 0, b.Length, null, null);
                int bytesRead = await Task.Factory.FromAsync<int>(asyncResult, s.EndRead);
            }
        }
        catch (System.IO.IOException)
        {
            return null;
        }

        int i = System.BitConverter.ToInt32(b, PeHeaderOffset);
        int secondsSince1970 = System.BitConverter.ToInt32(b, i + LinkerTimestampOffset);
        var dt = new DateTimeOffset(1970, 1, 1, 0, 0, 0, DateTimeOffset.Now.Offset) + DateTimeOffset.Now.Offset;
        dt = dt.AddSeconds(secondsSince1970);
        return dt;
    }

Uwaga: we wszystkich przypadkach używasz piaskownicy, więc będziesz w stanie uzyskać tylko czas kompilacji zestawów, które wdrażasz za pomocą aplikacji. (tzn. to nie zadziała na niczym w GAC).

 8
Author: Matt Dotson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-21 02:54:38

Powyższa metoda może być zmodyfikowana dla złożeń już załadowanych w procesie , używając obrazu pliku w pamięci (w przeciwieństwie do ponownego odczytu z magazynu):

using System;
using System.Runtime.InteropServices;
using Assembly = System.Reflection.Assembly;

static class Utils
{
    public static DateTime GetLinkerDateTime(this Assembly assembly, TimeZoneInfo tzi = null)
    {
        // Constants related to the Windows PE file format.
        const int PE_HEADER_OFFSET = 60;
        const int LINKER_TIMESTAMP_OFFSET = 8;

        // Discover the base memory address where our assembly is loaded
        var entryModule = assembly.ManifestModule;
        var hMod = Marshal.GetHINSTANCE(entryModule);
        if (hMod == IntPtr.Zero - 1) throw new Exception("Failed to get HINSTANCE.");

        // Read the linker timestamp
        var offset = Marshal.ReadInt32(hMod, PE_HEADER_OFFSET);
        var secondsSince1970 = Marshal.ReadInt32(hMod, offset + LINKER_TIMESTAMP_OFFSET);

        // Convert the timestamp to a DateTime
        var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        var linkTimeUtc = epoch.AddSeconds(secondsSince1970);
        var dt = TimeZoneInfo.ConvertTimeFromUtc(linkTimeUtc, tzi ?? TimeZoneInfo.Local);
        return dt;
    }
}
 8
Author: tcostin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-15 20:09:50

Jeśli chodzi o technikę pobierania daty kompilacji/informacji o wersji z bajtów nagłówka PE assembly, Microsoft zmienił domyślne parametry kompilacji, począwszy od Visual Studio 15.4. Nowa wartość domyślna zawiera deterministyczną kompilację, która sprawia, że ważny znacznik czasu i automatycznie zwiększane numery wersji należą do przeszłości. Pole timestamp jest nadal obecne, ale zostaje wypełnione stałą wartością, która jest Hashem czegoś lub innego, ale nie wskazuje na kompilację czas.

Http://blog.paranoidcoding.com/2016/04/05/deterministic-builds-in-roslyn.html niektóre szczegółowe tło tutaj

Dla tych, którzy przedkładają użyteczny znacznik czasu nad deterministyczną kompilację, istnieje sposób na nadpisanie nowej wartości domyślnej. Możesz dołączyć tag w .plik CSPROJ zgromadzenia interesów w następujący sposób:

  <PropertyGroup>
      ...
      <Deterministic>false</Deterministic>
  </PropertyGroup>

Update: Popieram rozwiązanie szablonu tekstowego T4 opisane w innej odpowiedzi tutaj. Użyłem go, aby rozwiązać mój problem czysto bez utraty korzyści z deterministycznej kompilacji. Należy pamiętać, że Visual Studio uruchamia kompilator T4 tylko wtedy, gdy plik .tt jest zapisywany, a nie w czasie kompilacji. Może to być niezręczne, jeśli wykluczyć .cs wynika z kontroli źródła (ponieważ spodziewasz się, że zostanie wygenerowany), a inny programista sprawdza kod. Bez ponownego zapisywania nie będą mieli .plik cs. Na nuget jest pakiet (chyba o nazwie AutoT4), który sprawia, że kompilacja T4 jest częścią każdej kompilacji. Nie mam jeszcze rozwiązanie tego problemu pojawiło się podczas wdrażania produkcji, ale spodziewam się czegoś podobnego, aby to naprawić.

 8
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-14 17:49:39

Wiele świetnych odpowiedzi tutaj, ale czuję, że mogę dodać własne ze względu na prostotę, wydajność (w porównaniu do rozwiązań związanych z zasobami) cross platform (działa również z Net Core) i unikanie jakichkolwiek narzędzi innych firm. Wystarczy dodać ten cel msbuild do csproj.

<Target Name="Date" BeforeTargets="CoreCompile">
    <WriteLinesToFile File="$(IntermediateOutputPath)gen.cs" Lines="static partial class Builtin { public static long CompileTime = $([System.DateTime]::UtcNow.Ticks) %3B }" Overwrite="true" />
    <ItemGroup>
        <Compile Include="$(IntermediateOutputPath)gen.cs" />
    </ItemGroup>
</Target>

A teraz masz Builtin.CompileTime lub new DateTime(Builtin.CompileTime, DateTimeKind.Utc) jeśli tego potrzebujesz.

Resharperowi się to nie spodoba. Możesz go zignorować lub dodać część klasy do projektu, ale to i tak działa.
 3
Author: Dmitry Gusarov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-18 08:06:16

Możesz użyć zdarzenia po zbudowaniu projektu, aby zapisać plik tekstowy do katalogu docelowego z bieżącą datetime. Następnie można odczytać wartość w czasie wykonywania. To trochę trudne, ale powinno zadziałać.

 2
Author: MikeWyatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-21 13:58:47

Nie jestem pewien, ale może Build Incrementer pomoże.

 2
Author: Bobby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-28 02:36:19

Innym, przyjaznym dla PCL podejściem byłoby użycie zadania wbudowanego MSBuild do zastąpienia czasu kompilacji łańcuchem znaków zwracanym przez właściwość w aplikacji. Z powodzeniem stosujemy to podejście w aplikacji, która ma Xamarin.Formularze, Xamarin.Android i Xamarin.projekty iOS.

EDIT:

Uproszczone przez przeniesienie całej logiki do pliku SetBuildDate.targets i użycie Regex zamiast prostego ciągu znaków replace, aby plik mógł być modyfikowany przez każdą kompilację bez "reset".

Wbudowana definicja zadania MSBuild (zapisana w SetBuildDate.plik docelowy lokalny do Xamarin.Projekt formularzy dla tego przykładu):

<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' ToolsVersion="12.0">

  <UsingTask TaskName="SetBuildDate" TaskFactory="CodeTaskFactory" 
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
    <ParameterGroup>
      <FilePath ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Code Type="Fragment" Language="cs"><![CDATA[

        DateTime now = DateTime.UtcNow;
        string buildDate = now.ToString("F");
        string replacement = string.Format("BuildDate => \"{0}\"", buildDate);
        string pattern = @"BuildDate => ""([^""]*)""";
        string content = File.ReadAllText(FilePath);
        System.Text.RegularExpressions.Regex rgx = new System.Text.RegularExpressions.Regex(pattern);
        content = rgx.Replace(content, replacement);
        File.WriteAllText(FilePath, content);
        File.SetLastWriteTimeUtc(FilePath, now);

   ]]></Code>
    </Task>
  </UsingTask>

</Project>

Wywołanie powyższego zadania inline w Xamarin.Forms CSPROJ file in target BeforeBuild:

  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.  -->
  <Import Project="SetBuildDate.targets" />
  <Target Name="BeforeBuild">
    <SetBuildDate FilePath="$(MSBuildProjectDirectory)\BuildMetadata.cs" />
  </Target>

Właściwość FilePath jest ustawiona na plik BuildMetadata.cs w Xamarin.Projekt Forms, który zawiera prostą klasę z właściwością string BuildDate, w której podstawiony zostanie czas kompilacji:

public class BuildMetadata
{
    public static string BuildDate => "This can be any arbitrary string";
}

Dodaj ten plik BuildMetadata.cs do projekt. Będzie on modyfikowany przez każdą kompilację, ale w sposób pozwalający na powtarzające się Kompilacje( powtarzające się zamienniki), więc możesz włączyć lub pominąć go w kontroli źródła zgodnie z życzeniem.

 2
Author: Mark Larter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-10 14:10:22

W 2018 roku niektóre z powyższych rozwiązań nie działają już lub nie działają z. Net Core.

Używam następującego podejścia, które jest proste i działa dla mojego projektu. NET Core 2.0.

Dodaj do swojego .csproj wewnątrz PropertyGroup:

    <Today>$([System.DateTime]::Now)</Today>

Definiuje to właściwość PropertyFunction , do której można uzyskać dostęp za pomocą polecenia pre build.

Twój pre-build wygląda tak

echo $(today) > $(ProjectDir)BuildTimeStamp.txt

Ustawia właściwość BuildTimeStamp.txt do Embedded zasoby.

Teraz możesz odczytać znacznik czasu w ten sposób

public static class BuildTimeStamp
    {
        public static string GetTimestamp()
        {
            var assembly = Assembly.GetEntryAssembly(); 

            var stream = assembly.GetManifestResourceStream("NamespaceGoesHere.BuildTimeStamp.txt");

            using (var reader = new StreamReader(stream))
            {
                return reader.ReadToEnd();
            }
        }
    }
 2
Author: Postlagerkarte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-12 15:04:52

Potrzebowałem uniwersalnego rozwiązania, które współpracowało 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:

param($outputFile="BuildDate.cs")

$buildDate = Get-Date -date (Get-Date).ToUniversalTime() -Format o
$class = 
"using System;
using System.Globalization;

namespace MyNamespace
{
    public static class BuildDate
    {
        public const string BuildDateString = `"$buildDate`";
        public static readonly DateTime BuildDateUtc = DateTime.Parse(BuildDateString, null, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
    }
}"

Set-Content -Path $outputFile -Value $class

Zapisz plik PowerScript jako GenBuildDate. ps1 i dodaj go do swojego projektu. Na koniec dodaj następujący wiersz do zdarzenia Pre-Build:

powershell -File $(ProjectDir)GenBuildDate.ps1 -outputFile $(ProjectDir)BuildDate.cs

Upewnij się BuildDate.cs jest zawarty w Twoim projekcie. Działa jak mistrz na każdym OS!

 2
Author: David Tosi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 16:21:52

Mała aktualizacja odpowiedzi" New Way " od Jhon.

Musisz zbudować ścieżkę zamiast używać ciągu kodu podczas pracy z ASP.NET/MVC

    var codeBase = assembly.GetName().CodeBase;
    UriBuilder uri = new UriBuilder(codeBase);
    string path = Uri.UnescapeDataString(uri.Path);
 2
Author: Thadeu Antonio Ferreira Melo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-04 13:21:58

W przypadku projektów. NET Core dostosowałem odpowiedź Postlagerkarte, aby zaktualizować pole praw autorskich do montażu o datę budowy.

Bezpośrednio Edytuj csproj

Do pierwszego PropertyGroup w csproj można dodać:

<Copyright>Copyright © $([System.DateTime]::UtcNow.Year) Travis Troyer ($([System.DateTime]::UtcNow.ToString("s")))</Copyright>

Alternatywa: Visual Studio Project Properties

Lub wklej wewnętrzne wyrażenie bezpośrednio do pola Prawa autorskie w sekcji Pakiet właściwości projektu w Visual Studio:

Copyright © $([System.DateTime]::UtcNow.Year) Travis Troyer ($([System.DateTime]::UtcNow.ToString("s")))

To może być trochę mylące, ponieważ Visual Studio oceni wyrażenie i wyświetli bieżącą wartość w oknie, ale również odpowiednio zaktualizuje plik projektu za kulisami.

Rozwiązanie w całym katalogu.Buduj.rekwizyty

Można przeciągnąć powyższy element <Copyright> do pliku {[7] } w katalogu głównym rozwiązania i automatycznie zastosować go do wszystkich projektów w katalogu, zakładając, że każdy projekt nie dostarcza własnej wartości praw autorskich.

<Project>
 <PropertyGroup>
   <Copyright>Copyright © $([System.DateTime]::UtcNow.Year) Travis Troyer ($([System.DateTime]::UtcNow.ToString("s")))</Copyright>
 </PropertyGroup>
</Project>

Katalog.Buduj.rekwizyty: Dostosuj swój build

Wyjście

Przykładowe wyrażenie da Ci prawa autorskie takie jak:

Copyright © 2018 Travis Troyer (2018-05-30T14:46:23)

Odzyskiwanie

Możesz wyświetlić informacje o prawach autorskich z właściwości pliku w systemie Windows lub pobrać je w czasie wykonywania:

var version = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location);

Console.WriteLine(version.LegalCopyright);
 2
Author: Travis Troyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-30 15:03:00

Możesz uruchomić dodatkowy krok w procesie budowania, który zapisze znacznik daty do pliku, który następnie będzie wyświetlany.

Na karcie Właściwości projektów spójrz na kartę Zdarzenia budowania. Istnieje możliwość wykonania polecenia Pre lub post build.

 1
Author: Guy van den Berg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-21 13:58:39

Użyłem sugestii Abdurrahima. Jednak wydawało się, że podał dziwny format czasu, a także dodał Skrót dnia jako część daty budowy; przykład:Sun 24/12/2017 13:21: 05.43. Potrzebowałem tylko daty, więc musiałem wyeliminować resztę za pomocą podłańcucha.

Po dodaniu echo %date% %time% > "$(ProjectDir)\Resources\BuildDate.txt"do zdarzenia pre-build wykonałem następujące czynności:

string strBuildDate = YourNamespace.Properties.Resources.BuildDate;
string strTrimBuildDate = strBuildDate.Substring(4).Remove(10);
Dobra wiadomość jest taka, że zadziałało.
 1
Author: DemarcPoint,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-24 20:57:53

Jeśli jest to aplikacja dla systemu windows, możesz po prostu użyć ścieżki wykonywalnej aplikacji: nowy System. IO. FileInfo (Application.ExecutablePath).LastWriteTime.ToString ("yyyy.MM.dd")

 0
Author: John Clark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-19 14:25:05

Możesz użyć tego projektu: https://github.com/dwcullop/BuildInfo

Wykorzystuje T4 do automatyzacji znacznika czasu daty kompilacji. Istnieje kilka wersji (różne gałęzie), w tym jedna, która daje Ci Git Hash aktualnie sprawdzonej gałęzi, jeśli lubisz takie rzeczy.

Disclosure: napisałem moduł.

 0
Author: Darrin Cullop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-22 20:29:27