O caminho
Como apontado por @ c00000fd nos comentários . A Microsoft está mudando isso. E enquanto muitas pessoas não usam a versão mais recente de seu compilador, suspeito que essa mudança torne essa abordagem inquestionavelmente ruim. E, embora seja um exercício divertido, eu recomendaria que as pessoas simplesmente incorporassem uma data de construção em seu binário por qualquer outro meio necessário, se for importante rastrear a data de construção do próprio binário.
Isso pode ser feito com alguma geração trivial de código, que provavelmente já é a primeira etapa do seu script de construção. Isso e o fato de as ferramentas ALM / Build / DevOps ajudarem muito com isso e devem ser preferidas a qualquer outra coisa.
Deixo o restante desta resposta aqui apenas para fins históricos.
O novo caminho
Mudei de idéia sobre isso e, atualmente, use esse truque para obter a data de compilação correta.
#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
O jeito antigo
Bem, como você gera números de compilação? O Visual Studio (ou o compilador C #) realmente fornece números de compilação e revisão automáticos se você alterar o atributo AssemblyVersion para, por exemplo,1.0.*
O que acontecerá é que a compilação será igual ao número de dias desde 1º de janeiro de 2000, horário local, e a revisão será igual ao número de segundos desde o horário local da meia-noite, dividido por 2.
consulte Conteúdo da comunidade, números de compilação e revisão automáticos
por exemplo 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)