La manera
Como señaló @ c00000fd en los comentarios . Microsoft está cambiando esto. Y aunque muchas personas no usan la última versión de su compilador, sospecho que este cambio hace que este enfoque sea indudablemente malo. Y aunque es un ejercicio divertido, recomendaría a las personas que simplemente incorporen una fecha de compilación en su binario a través de cualquier otro medio necesario si es importante rastrear la fecha de compilación del propio binario.
Esto se puede hacer con una generación de código trivial que probablemente ya sea el primer paso en su script de compilación. Eso y el hecho de que las herramientas ALM / Build / DevOps ayudan mucho con esto y deberían preferirse a cualquier otra cosa.
Dejo el resto de esta respuesta aquí solo con fines históricos.
La nueva forma
Cambié de opinión sobre esto, y actualmente uso este truco para obtener la fecha de compilación correcta.
#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
La vieja manera
Bueno, ¿cómo generas números de compilación? Visual Studio (o el compilador de C #) en realidad proporciona números de compilación y revisión automáticos si cambia el atributo AssemblyVersion a, p. Ej.1.0.*
Lo que sucederá es que la compilación será igual a la cantidad de días desde el 1 de enero de 2000, hora local, y que la revisión sea igual a la cantidad de segundos desde la medianoche, hora local, dividida por 2.
ver Contenido de la comunidad, Números automáticos de compilación y revisión
eg 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)