Search code examples
vb.netvisual-studiobuild-events

Setting the value of a constant or variable at build time


I would like to have a Constant or field defined in my application startup code that reflect the date that the application was actually built. Something like for example:

 Private Shared ApplicationBuiltOn As Date = <and here is where I would like to set the build date>`

Can this be done using build events so that it is always set and I don't actively have to remember to do it prior to actively building a release version.

If it is possible how does one do it? I've read through the msdn documentation on build events but nothing seems to cover what I'd like to try and do.


Solution

  • You could try this (tested it and worked for me)

    Public NotInheritable Class ApplicationInformation
        Private Sub New()
        End Sub
        ''' <summary>
        ''' Gets the executing assembly.
        ''' </summary>
        ''' <value>The executing assembly.</value>
        Public Shared ReadOnly Property ExecutingAssembly() As System.Reflection.Assembly
            Get
                Return If(m_executingAssembly, (InlineAssignHelper(m_executingAssembly, System.Reflection.Assembly.GetExecutingAssembly())))
            End Get
        End Property
        Private Shared m_executingAssembly As System.Reflection.Assembly
    
        ''' <summary>
        ''' Gets the executing assembly version.
        ''' </summary>
        ''' <value>The executing assembly version.</value>
        Public Shared ReadOnly Property ExecutingAssemblyVersion() As System.Version
            Get
                Return If(m_executingAssemblyVersion, (InlineAssignHelper(m_executingAssemblyVersion, ExecutingAssembly.GetName().Version)))
            End Get
        End Property
        Private Shared m_executingAssemblyVersion As System.Version
    
        ''' <summary>
        ''' Gets the compile date of the currently executing assembly.
        ''' </summary>
        ''' <value>The compile date.</value>
        Public Shared ReadOnly Property CompileDate() As System.DateTime
            Get
                If Not m_compileDate.HasValue Then
                    m_compileDate = RetrieveLinkerTimestamp(ExecutingAssembly.Location)
                End If
                Return If(m_compileDate, New System.DateTime())
            End Get
        End Property
        Private Shared m_compileDate As System.Nullable(Of System.DateTime)
    
        ''' <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</remarks>
        Private Shared Function RetrieveLinkerTimestamp(filePath As String) As System.DateTime
            Const  peHeaderOffset As Integer = 60
            Const  linkerTimestampOffset As Integer = 8
            Dim b = New Byte(2047) {}
            Dim s As System.IO.FileStream = Nothing
            Try
                s = New System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)
                s.Read(b, 0, 2048)
            Finally
                If s IsNot Nothing Then
                    s.Close()
                End If
            End Try
            Dim 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)
        End Function
        Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
            target = value
            Return value
        End Function
    End Class
    

    And use it like this:

    Messagebox.Show("This application was built on: " & ApplicationInformation.CompileDate.ToString())
    

    NOTE: Grabbed together from https://stackoverflow.com/a/3634544/4237809 and http://blog.codinghorror.com/determining-build-date-the-hard-way/