11

Hope fully the title was somewhat descriptive.

I have a winform application written in C# with .net 2.0. I would like to have the last compile date automatically updated to a variable for use in the about box and initial splash box. Currently I have a string variable that I update manually. Is there any way to do this?

VS2008 .net 2.0 c#

Brad
  • 20,302
  • 36
  • 84
  • 102

5 Answers5

7

Another trick (which you may not be able to use) is to leverage the automatic build and revision numbers generated by .NET. If your AssemblyInfo has:

[assembly: AssemblyVersion("1.0.*")]

The last two numbers are just a date/time stamp. Some code (list below) may help:

Version v = Assembly.GetExecutingAssembly().GetName().Version;
DateTime compileDate = new DateTime((v.Build - 1) * TimeSpan.TicksPerDay + v.Revision * TimeSpan.TicksPerSecond * 2).AddYears(1999);

Edit: here's an alternative answer that may be a little clearer to follow than what I put: https://stackoverflow.com/a/804895/2258

Community
  • 1
  • 1
Richard Morgan
  • 7,601
  • 9
  • 49
  • 86
  • 1
    Beware ! This code doesn't work when you build something on March 11 2012 (because of leap year ?) : it returns March 12 instead of March 11. – JYL Mar 11 '12 at 09:46
5

Pop this into your pre-build events;

echo public static class DateStamp { public readonly static System.DateTime BuildTime = System.DateTime.Parse("%date%"); }  > $(ProjectDir)DateStamp.cs

It creates a class called DateStamp like this;

public static class DateStamp
{ 
   public readonly static System.DateTime BuildTime = System.DateTime.Parse("14/12/2009"); 
}

And you use it like this;

Console.WriteLine("Build on " + DateStamp.BuildTime.ToShortDateString());
Steve Cooper
  • 20,542
  • 15
  • 71
  • 88
  • how do I get it to recognize "DateStamp" prior to build? I get the error ...The name 'DateStamp' does not exist in the current context – Brad Dec 14 '09 at 22:01
  • Ah, right. The file (DateStamp.cs) will be in the root folder of your project. In VS, go to the solution explorer and click the button which shows all files, including the ones not currently in your project. Find DateStamp.cs, right-click it, and choose 'include in project'. You should now find it builds as part of your project. – Steve Cooper Dec 15 '09 at 00:38
3

This might be a decade too late to be useful, but maybe it'll help someone else.

You can add this target to your csproj file, just paste it in at the end:

 <Target Name="BuildDate" BeforeTargets="CoreCompile">
    <PropertyGroup>
      <SharedAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</SharedAssemblyInfoFile>
    </PropertyGroup>
    <ItemGroup>
      <Compile Include="$(SharedAssemblyInfoFile)" />
    </ItemGroup>
    <ItemGroup>
      <AssemblyAttributes Include="AssemblyMetadata">
        <_Parameter1>AssemblyDate</_Parameter1>
        <_Parameter2>$([System.DateTime]::UtcNow.ToString("u"))</_Parameter2>
      </AssemblyAttributes>
    </ItemGroup>
    <WriteCodeFragment Language="C#" OutputFile="$(SharedAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
  </Target>

This will create a CustomAssemblyInfo.cs file in your "obj" folder, that contains a single line: [assembly: AssemblyMetadata("AssemblyDate", "DATE_OF_BUILD_HERE")] This file will be compiled into your assembly, so you can access it at runtime using reflection, such as with the following code:

using System;
using System.Linq;
using System.Reflection;

public class Application
{
    static DateTime BuildDate;
    public static DateTime GetBuildDate()
    {
        if (BuildDate == default(DateTime)) {
            var attr = typeof(Application).Assembly.GetCustomAttributes<AssemblyMetadataAttribute>();
            var dateStr = attr.Single(a => a.Key == "AssemblyDate")?.Value;
            BuildDate = DateTime.Parse(dateStr);
        }
        return BuildDate;
    }
}

One thing to note, the AssemblyMetadataAttribute that I'm using here was only added in .NET 4.5.3, so if you need to support a version previous to that you can simply define your own custom attribute type to hold the date value.

MarkPflug
  • 28,292
  • 8
  • 46
  • 54
  • This solution is great... but I'm using it in a legacy ASP.NET WebForms project and it seems to break "Publish" builds (VS complains about missing arguments for `AssemblyMetadataAttribute`) - but the weird thing is that if I do an initial normal proejct build first, and _then_ do a Publish build it works. Weird. – Dai Apr 22 '20 at 07:38
  • 1
    this gets: System.InvalidOperationException: 'Sequence contains no matching element' – Jerryno Jan 07 '21 at 05:23
1

I used this about box from codeproject.com. It was actually written by Jeff Atwood way back in 2004. It figures out the compile time by looking at the date stamp on the assembly file, or calculating it from the assembly version. Perhaps you could extract the relevant code from there.

Don Kirkby
  • 53,582
  • 27
  • 205
  • 286
0

There is no inbuilt macro or similar for this. Your best bet might be a custom build task, such as on tigris, using the Time task and RegexReplace or similar. Not simple to get right. Personally I use the repository version to update AssemblyInfo - broadly related?

<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
...
<SvnInfo LocalPath=".">
  <Output TaskParameter="Revision" PropertyName="BuildRev" />
</SvnInfo>
<FileUpdate Files="protobuf-net\Properties\AssemblyInfo.cs"
        Regex='(\[\s*assembly:\s*AssemblyVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])'
        ReplacementText='$1.$2.$(BuildRev)$5' />
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900