Question

In C# 3.0, I have a property which is suppose to contain the version of the class. The version number is simply the date and time of compilation. Right now, I have the following code:

public DateTime Version
{
    get { return DateTime.UtcNow; }
}

Obviously, this is wrong since this property returns me the current date and time. So, is the precompiler can print the DateTime at compile time? In this case, I could do something similar to below.

public DateTime Version
{
    get { return new DateTime("PRECOMPILER DATE"); }
}
Was it helpful?

Solution

C# doesn't have the concept of macros; however, you can use other tools in your build script (csproj / NANT / etc) to manipulate the source before it compiles. I use this, for example, to set the revision number to the current SVN revision.

A cheap option is a pre-build event (you can do this via the project properties dialog in VS): essentially a bat file that runs before build; you can then script whatever changes you need. A more sophisticated option is build tasks.

For example, the utility library here includes a Time task and a FileUpdate task; it should (in theory) be possible to chain the two together to emulate what you need.

Personally, I'd use the [AssemblyVersion] details rather than the time - if you link this to your source-control system, this makes it very easy to find the offending version; so for my SVN version, I then use (in my build proj):

<!-- See http://msbuildtasks.tigris.org -->
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
...
<SvnInfo LocalPath=".">
  <Output TaskParameter="Revision" PropertyName="BuildRev" />
</SvnInfo>
...
<FileUpdate Files="Path\To\My\AssemblyInfo.cs"
    Regex='(\[\s*assembly:\s*AssemblyVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])'
    ReplacementText='$1.$2.$(BuildRev)$5' />
<FileUpdate Files="Path\To\My\AssemblyInfo.cs"
    Regex='(\[\s*assembly:\s*AssemblyFileVersion\(\s*"[^\.]+\.[^\.]+)\.([^\.]+)(\.)([^\.]+)("\)\s*\])'
    ReplacementText='$1.$2.$(BuildRev)$5' />

And now my assembly-version is correct, including the file-version that gets reported by the OS.

OTHER TIPS

You can retreive it from the dll itself (Source: codinghorror)

   private DateTime RetrieveLinkerTimestamp() {
        string filePath = System.Reflection.Assembly.GetCallingAssembly().Location;
        const int c_PeHeaderOffset = 60;
        const int c_LinkerTimestampOffset = 8;
        byte[] b = new byte[2048];
        System.IO.Stream s = null;

        try {
            s = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            s.Read(b, 0, 2048);
        } finally {
            if (s != null) {
                s.Close();
            }
        }

        int i = System.BitConverter.ToInt32(b, c_PeHeaderOffset);
        int secondsSince1970 = System.BitConverter.ToInt32(b, i + c_LinkerTimestampOffset);
        DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0);
        dt = dt.AddSeconds(secondsSince1970);
        dt = dt.AddHours(TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours);
        return dt;
    }

There's no equivalent for the __TIME__ preprocessor directive in C#, The best you could do is get the current assembly and get the created date, it will contain the compile time. See here

I don't think there's a way to do this in C# - C++ style macro definitions are explictly disallowed.

You could work around it using either the last modified date of the assembly, or potentially include a text file as an embedded resource and add a custom build action that writes the current date/time into it.

There's no preprocessor __TIME__ directive, but there's other things you could use, such as the creation time of the assembly. You might also consider using keyword substitution from your source control system ($Date$ in subversion).

The Build number can be retrieved from the metadata of an assembly, and can be set to match with the date of the build.

Normally you will find, or create an entry in the AssemblyInfo.cs file. When your project is created using Visual Studio. An example:

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

A quote for the documentation on AssemblyVersionAttribute. (I've bolded some important parts)

You can specify all the values or you can accept the default build number, revision number, or both by using an asterisk (). For example, [assembly:AssemblyVersion("2.3.25.1")] indicates 2 as the major version, 3 as the minor version, 25 as the build number, and 1 as the revision number. A version number such as [assembly:AssemblyVersion("1.2.")] specifies 1 as the major version, 2 as the minor version, and accepts the default build and revision numbers. A version number such as [assembly:AssemblyVersion("1.2.15.*")] specifies 1 as the major version, 2 as the minor version, 15 as the build number, and accepts the default revision number. The default build number increments daily. The default revision number is random.

As you can see, if you can set a default build number with this. The default build number is a value that is incremented every day.

You can then retrieve the Build number by using the AssemblyName.Version property. The examples provided by MSDN should get you going.

The default build number is the number of days since 1/1/2000.

This question also has a clear explanation on how to use this.

Do you looking for something like this:
(Get's the Date of Building the Assembly via Version-Info; Build-Number is days since 1.1.2000)

         var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
        DateTime versionsDatum = new DateTime(2000, 1, 1);
        versionsDatum = versionsDatum.AddDays(version.Build);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top