道
コメントで @ c00000fdが指摘したように。マイクロソフトはこれを変更しています。また、多くの人々はコンパイラの最新バージョンを使用していませんが、この変更によりこのアプローチが間違いなく悪いものになると思います。楽しい演習ですが、バイナリ自体のビルド日付を追跡することが重要な場合は、必要な他の方法でバイナリにビルド日付を埋め込むことをお勧めします。
これは、おそらく既にビルドスクリプトの最初のステップである、いくつかの簡単なコード生成で行うことができます。それと、ALM /ビルド/ DevOpsツールがこれに大きく役立ち、他のツールよりも優先されるはずです。
この回答の残りは、ここでは歴史的な目的のためにのみ残しておきます。
新しい方法
私はこれについて考えを変え、現在このトリックを使用して正しいビルド日付を取得しています。
#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
古い方法
さて、どのようにビルド番号を生成しますか?Visual Studio(またはC#コンパイラ)は、AssemblyVersion属性をたとえば1.0.*
これは、ビルドが2000年1月1日の現地時間からの日数に等しくなり、リビジョンが現地時間の午前0時からの秒数を2で割ったものになるということです。
コミュニティコンテンツを参照してください。 自動ビルド、リビジョン番号を
例: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)