Displaying the build date

前端 未结 25 2026
感动是毒
感动是毒 2020-11-22 11:36

I currently have an app displaying the build number in its title window. That\'s well and good except it means nothing to most of the users, who want to know if they have t

相关标签:
25条回答
  • 2020-11-22 12:12

    Add below to pre-build event command line:

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

    Add this file as resource, now you have 'BuildDate' string in your resources.

    After inserting the file into the Resource (as public text file), I accessed it via

    string strCompTime = Properties.Resources.BuildDate;
    

    To create resources, see How to create and use resources in .NET.

    0 讨论(0)
  • 2020-11-22 12:12

    If this is a windows app, you can just use the application executable path: new System.IO.FileInfo(Application.ExecutablePath).LastWriteTime.ToString("yyyy.MM.dd")

    0 讨论(0)
  • 2020-11-22 12:13

    I am just C# newbie so maybe my answer sound silly - I display the build date from the date the executable file was last written to:

    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());
    

    I tried to use File.GetCreationTime method but got weird results: the date from the command was 2012-05-29, but the date from the Window Explorer showed 2012-05-23. After searching for this discrepancy I found that the file was probably created on 2012-05-23 (as shown by Windows Explorer), but copied to the current folder on 2012-05-29 (as shown by File.GetCreationTime command) - so to be on the safe side I am using File.GetLastWriteTime command.

    Zalek

    0 讨论(0)
  • 2020-11-22 12:13

    I'm not sure, but maybe the Build Incrementer helps.

    0 讨论(0)
  • 2020-11-22 12:14

    The way

    As pointed out by @c00000fd in the comments. Microsoft is changing this. And while many people don't use the latest version of their compiler I suspect this change makes this approach unquestionably bad. And while it's a fun exercise I would recommend people to simply embed a build date into their binary through any other means necessary if it's important to track the build date of the binary itself.

    This can be done with some trivial code generation which probably is the first step in your build script already. That, and the fact that ALM/Build/DevOps tools help a lot with this and should be preferred to anything else.

    I leave the rest of this answer here for historical purposes only.

    The new way

    I changed my mind about this, and currently use this trick to get the correct build date.

    #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

    Well, how do you generate build numbers? Visual Studio (or the C# compiler) actually provides automatic build and revision numbers if you change the AssemblyVersion attribute to e.g. 1.0.*

    What will happen is that is that the build will be equal to the number of days since January 1, 2000 local time, and for revision to be equal to the number of seconds since midnight local time, divided by 2.

    see Community Content, Automatic Build and Revision numbers

    e.g. 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)
    
    0 讨论(0)
  • 2020-11-22 12:14

    The option not discussed here is to insert your own data into AssemblyInfo.cs, the "AssemblyInformationalVersion" field seems appropriate - we have a couple of projects where we were doing something similar as a build step (however I'm not entirely happy with the way that works so don't really want to reproduce what we've got).

    There's an article on the subject on codeproject: http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspx

    0 讨论(0)
提交回复
热议问题