One of the key diagnostic data points for any .NET assembly is "when was it built"? Until recently, I thought there were only two ways to suss this out:
Thanks for that! Iāll correct and update that post over the next few days.
Iāve read your blog before. Nice to see stuff about VB.NET. Iām not the biggest VB.NET fan, but I seem to end up using it a lot and itās not going away.
That whole ānumber of daysā and ānumber of secondsā thing made me nervous, even without having to open and close the IDE. Even though some people passionately explained to me why itās a good thing, those numbers seem basically random and make it hard to know what version you are in fact looking at. So I (and lots of others) wrote a little VS macro to update the build number every time I do a build, and I update the other three according to the bigness of the change. Then the file version is pretty useful, I think.
Though, upon considering your post, I realize that my method doesnāt tell you anything about when the file was actually built. I bet another macro could be used to take this string and write it as a resource in the executable. Probably not as sexy as Dustinās approach though.
So I (and lots of others) wrote a little VS macro to update the build number every time I do a build
Yes, thatās certainly logical. But it begs the question: why didnāt Microsoft do it this way? Oversight? Or did they just want to ensure the build and revision number are different every time in the absence of any real metadata provided by the developer?
My method doesnāt tell you anything about when the file was actually built.
Right, and build # is kind of a meaningless number anyway. Does anyone remember the build number of the first release of NT 4.0? of XP? The date of the build is much more useful information than how many times the developers on the project happened to press the F5 key before it was packaged into a box and shippedā¦
The build hour and minutes not changing on each release .NET build compile caught me out. Norton AV prompted every time the binary changed, so Iād expected version number to change. Open/Close IDE ā nice tip!
Andy (above) thinks heās being clever, but in fact his curt little āerror reportā has robbed him of any chance of help. Well done you. It works perfectly for me, although it did take a few tries with asterisks and blanks around different places to get it going. (Iām on C# Express 2008) This is what patience and being polite gets you.
nice try but
Function RetrieveLinkerTimestamp() As DateTime
doesnāt change with each build cycle, :
Const PeHeaderOffset As Integer = 60
Const LinkerTimestampOffset As Integer = 8
Dim filePath = System.Reflection.Assembly.GetCallingAssembly().Location
Dim b(2047) As Byte
Dim s As Stream
Try
s = New FileStream(filePath, FileMode.Open, FileAccess.Read)
s.Read(b, 0, 2048)
Finally
If Not s Is Nothing Then s.Close()
End Try
Dim i As Integer = BitConverter.ToInt32(b, PeHeaderOffset)
Dim SecondsSince1970 As Integer = BitConverter.ToInt32(b, i + LinkerTimestampOffset)
Dim dt As New DateTime(1970, 1, 1, 0, 0, 0)
dt = dt.AddSeconds(SecondsSince1970)
dt = dt.AddHours(TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours)
Return dt
End Function
Thank you so much Joe. I just used your C# code and it worked like a charm. Our busy testing environment needed to have the latest version with latest build date set.
Could someone please explain how/why this works?
I see we get 4 bytes as int from the 60th byte in the PE and assign it to i.
Which I assuem is the time.
We then get prosumeably the seconds since 1970, which is found at ā¦
(i plus the constant 8)th byte in the PE.
So this means that the time we get from the PE is always in a different possition, which is dependant on the variable i (according to the code).