tags:

views:

319

answers:

6

How can I retrieve the Created date from the current .NET assembly?

I'd like to add some realy simple functionality where my app stops working one week after the build date of the main assembly. I already wrote the code that kills my app after a given date. I just need to programmatically retrieve the creation date from the assembly.

+1  A: 

This should work:

var entryAssembly = Assembly.GetEntryAssembly();
var fileInfo = new FileInfo(entryAssembly.Location);
var buildDate = fileInfo.LastWriteTime;
Jake Pearson
A: 

What's wrong with:

System.IO.File.GetLastWriteTime(Assembly.GetExecutingAssembly().Location);
Wim Hollebrandse
+2  A: 

I don't think the assembly itself contains it's creation date. I suspect the closest you can get is the creation date of the assembly file itself:

File.GetCreationTime(Assembly.GetExecutingAssembly().Location)

should do the trick.

Rob Levine
A: 

The best way to do this would be with a custom attribute that you set on the PreBuild of your assembly.

And then use the standard reflection to get the attribute you created.

But out of curiosity, why kill the app after the BUILD date?

Paulo Santos
Doesn't need to be the build date. I just picked that date because I knew that date would change automatically as the app is built. The goal, I only want to allow the app to function for about a week. I could also hardcode a date into the code but would need to change that variable as changes are made to the app.
Scott
@Scott but than your way to kill the app, is easily circumvented.
Paulo Santos
Killing the app based on build date seems like a good way of reducing noise when doing alpha testing in a unstructured environment (i.e. internet volunteers). This way you avoid people downloading the lastest alpha, forgetting it for 3 weeks, and then testing and reporting a lot of bugs that have already been dealt with. It ensures that alpha testers are always using a recent version of the app, without having something that could introduce even more bugs at that stage like an auto-update feature.
David
@Paul - you are correct. It is easily circumvented but this is not about security or copy protection. I need a quick and dirty way to put an expiration date on builds.
Scott
+6  A: 

Maybe this post on coding horror may help

jmlumpkin
+1 That worked great!
chaiguy
A: 

The following is based on: http://www.codinghorror.com/blog/2005/04/determining-build-date-the-hard-way.html

public static class ApplicationInformation
{
    /// <summary>
    /// Gets the executing assembly.
    /// </summary>
    /// <value>The executing assembly.</value>
    public static System.Reflection.Assembly ExecutingAssembly
    {
        get { return executingAssembly ?? (executingAssembly = System.Reflection.Assembly.GetExecutingAssembly()); }
    }
    private static System.Reflection.Assembly executingAssembly;

    /// <summary>
    /// Gets the executing assembly version.
    /// </summary>
    /// <value>The executing assembly version.</value>
    public static System.Version ExecutingAssemblyVersion
    {
        get { return executingAssemblyVersion ?? (executingAssemblyVersion = ExecutingAssembly.GetName().Version); }
    }
    private static System.Version executingAssemblyVersion;

    /// <summary>
    /// Gets the compile date of the currently executing assembly.
    /// </summary>
    /// <value>The compile date.</value>
    public static System.DateTime CompileDate
    {
        get
        {
            if (!compileDate.HasValue)
                compileDate = RetrieveLinkerTimestamp(ExecutingAssembly.Location);
            return compileDate ?? new System.DateTime();
        }
    }
    private static System.DateTime? compileDate;

    /// <summary>
    /// Retrieves the linker timestamp.
    /// </summary>
    /// <param name="filePath">The file path.</param>
    /// <returns></returns>
    /// <remarks>http://www.codinghorror.com/blog/2005/04/determining-build-date-the-hard-way.html&lt;/remarks&gt;
    private static System.DateTime RetrieveLinkerTimestamp(string filePath)
    {
        const int peHeaderOffset = 60;
        const int linkerTimestampOffset = 8;
        var b = new byte[2048];
        System.IO.FileStream 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();
        }
        var dt = new System.DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(System.BitConverter.ToInt32(b, System.BitConverter.ToInt32(b, peHeaderOffset) + linkerTimestampOffset));
        return dt.AddHours(System.TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours);
    }
}
grenade