Droga
Jak wskazał @ c00000fd w komentarzach . Microsoft to zmienia. I chociaż wiele osób nie korzysta z najnowszej wersji swojego kompilatora, podejrzewam, że ta zmiana czyni to podejście niewątpliwie złym. I chociaż jest to zabawne ćwiczenie, polecam ludziom, aby po prostu osadzili datę kompilacji w swoim pliku binarnym za pomocą wszelkich innych niezbędnych środków, jeśli ważne jest śledzenie daty kompilacji samego pliku binarnego.
Można to zrobić za pomocą trywialnego generowania kodu, który prawdopodobnie jest już pierwszym krokiem w skrypcie kompilacji. To oraz fakt, że narzędzia ALM / Build / DevOps bardzo w tym pomagają i powinny być preferowane w stosunku do wszystkiego innego.
Pozostałą część tej odpowiedzi pozostawiam tutaj wyłącznie do celów historycznych.
Nowy sposób
Zmieniłem zdanie na ten temat i obecnie używam tej sztuczki, aby uzyskać prawidłową datę kompilacji.
#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
Po staremu
Jak generujesz liczby kompilacji? Visual Studio (lub kompilator C #) faktycznie zapewnia automatyczne numery kompilacji i wersji, jeśli zmienisz atrybut AssemblyVersion na np1.0.*
Stanie się tak, że kompilacja będzie równa liczbie dni od 1 stycznia 2000 czasu lokalnego, a korekta będzie równa liczbie sekund od północy czasu lokalnego, podzielonej przez 2.
zobacz zawartość społeczności, automatyczne kompilacje i numery wersji
np. 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)