Displaying the build date

2018-12-31 14:41发布

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 the latest build - they tend to refer to it as "last Thursday's" rather than build 1.0.8.4321.

The plan is to put the build date there instead - So "App built on 21/10/2009" for example.

I'm struggling to find a programmatic way to pull the build date out as a text string for use like this.

For the build number, I used:

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

after defining how those came up.

I'd like something like that for the compile date (and time, for bonus points).

Pointers here much appreciated (excuse pun if appropriate), or neater solutions...

22条回答
与风俱净
2楼-- · 2018-12-31 15:08

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.

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

查看更多
荒废的爱情
3楼-- · 2018-12-31 15:13

Regarding the technique of pulling build date/version info from the bytes of an assembly PE header, Microsoft has changed the default build parameters beginning with Visual Studio 15.4. The new default includes deterministic compilation, which makes a valid timestamp and automatically incremented version numbers a thing of the past. The timestamp field is still present but it gets filled with a permanent value that is a hash of something or other, but not any indication of the build time.

http://blog.paranoidcoding.com/2016/04/05/deterministic-builds-in-roslyn.html Some detailed background here

For those who prioritize a useful timestamp over deterministic compilation, there is a way to override the new default. You can include a tag in the .csproj file of the assembly of interest as follows:

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

Update: I endorse the T4 text template solution described in another answer here. I used it to solve my issue cleanly without losing the benefit of deterministic compilation. One caution about it is that Visual Studio only runs the T4 compiler when the .tt file is saved, not at build time. This can be awkward if you exclude the .cs result from source control (since you expect it to be generated) and another developer checks out the code. Without resaving, they won't have the .cs file. There is a package on nuget (I think called AutoT4) that makes T4 compilation part of every build. I have not yet confronted the solution to this during production deployment, but I expect something similar to make it right.

查看更多
笑指拈花
4楼-- · 2018-12-31 15:13

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

查看更多
一个人的天荒地老
5楼-- · 2018-12-31 15:14

A small update on the "New Way" answer from Jhon.

You need to build the path instead of using the CodeBase string when working with ASP.NET/MVC

    var codeBase = assembly.GetName().CodeBase;
    UriBuilder uri = new UriBuilder(codeBase);
    string path = Uri.UnescapeDataString(uri.Path);
查看更多
深知你不懂我心
6楼-- · 2018-12-31 15:15

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")

查看更多
若你有天会懂
7楼-- · 2018-12-31 15:16

In 2018 some of the above solutions do not work anymore or do not work with .NET Core.

I use the following approach which is simple and works for my .NET Core 2.0 project.

Add the following to your .csproj inside the PropertyGroup :

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

This defines a PropertyFunction which you can access in your pre build command.

Your pre-build looks like this

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

Set the property of the BuildTimeStamp.txt to Embedded resource.

Now you can read the time stamp like this

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();
            }
        }
    }
查看更多
登录 后发表回答