Der Weg
Wie von @ c00000fd in den Kommentaren hervorgehoben . Microsoft ändert dies. Und obwohl viele Leute nicht die neueste Version ihres Compilers verwenden, vermute ich, dass diese Änderung diesen Ansatz zweifellos schlecht macht. Und während es eine lustige Übung ist, würde ich Leuten empfehlen, einfach ein Erstellungsdatum in ihre Binärdatei einzubetten, wenn es wichtig ist, das Erstellungsdatum der Binärdatei selbst zu verfolgen.
Dies kann mit einer trivialen Codegenerierung erfolgen, die wahrscheinlich bereits der erste Schritt in Ihrem Build-Skript ist. Das und die Tatsache, dass ALM / Build / DevOps-Tools dabei sehr hilfreich sind und allen anderen vorgezogen werden sollten.
Den Rest dieser Antwort lasse ich hier nur zu historischen Zwecken.
Der neue Weg
Ich habe es mir anders überlegt und verwende derzeit diesen Trick, um das richtige Erstellungsdatum zu erhalten.
#region Gets the build date and time (by reading the COFF header)
// http://msdn.microsoft.com/en-us/library/ms680313
struct _IMAGE_FILE_HEADER
{
public ushort Machine;
public ushort NumberOfSections;
public uint TimeDateStamp;
public uint PointerToSymbolTable;
public uint NumberOfSymbols;
public ushort SizeOfOptionalHeader;
public ushort Characteristics;
};
static DateTime GetBuildDateTime(Assembly assembly)
{
var path = assembly.GetName().CodeBase;
if (File.Exists(path))
{
var buffer = new byte[Math.Max(Marshal.SizeOf(typeof(_IMAGE_FILE_HEADER)), 4)];
using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
fileStream.Position = 0x3C;
fileStream.Read(buffer, 0, 4);
fileStream.Position = BitConverter.ToUInt32(buffer, 0); // COFF header offset
fileStream.Read(buffer, 0, 4); // "PE\0\0"
fileStream.Read(buffer, 0, buffer.Length);
}
var pinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try
{
var coffHeader = (_IMAGE_FILE_HEADER)Marshal.PtrToStructure(pinnedBuffer.AddrOfPinnedObject(), typeof(_IMAGE_FILE_HEADER));
return TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1) + new TimeSpan(coffHeader.TimeDateStamp * TimeSpan.TicksPerSecond));
}
finally
{
pinnedBuffer.Free();
}
}
return new DateTime();
}
#endregion
Der alte Weg
Wie generieren Sie Build-Nummern? Visual Studio (oder der C # -Compiler) bietet tatsächlich automatische Build- und Revisionsnummern, wenn Sie das AssemblyVersion-Attribut in z1.0.*
Was passieren wird, ist, dass der Build der Anzahl der Tage seit dem 1. Januar 2000 Ortszeit entspricht und dass die Revision der Anzahl der Sekunden seit Mitternacht Ortszeit entspricht, geteilt durch 2.
Siehe Community-Inhalt, automatische Build- und Revisionsnummern
zB AssemblyInfo.cs
[assembly: AssemblyVersion("1.0.*")] // important: use wildcard for build and revision numbers!
SampleCode.cs
var version = Assembly.GetEntryAssembly().GetName().Version;
var buildDateTime = new DateTime(2000, 1, 1).Add(new TimeSpan(
TimeSpan.TicksPerDay * version.Build + // days since 1 January 2000
TimeSpan.TicksPerSecond * 2 * version.Revision)); // seconds since midnight, (multiply by 2 to get original)