補足:この記事では、「.NET Framework」を.NET Framework 4.8までのこと、「.NET」.NET5以降主に.NET8の事を示します。
.NET前の.NET Framework時代のアプリケーションでは、AssemblyInfo.csに次のように書いておけば、ビルドするたびにビルドバージョンとリビジョンに日付と時刻を使ったバージョン(プロダクトバージョン)を付与して自動的に埋め込むことができました。
[assembly: AssemblyVersion("1.0.*")]
// 取り出し方 var version = Assembly.GetExecutingAssembly().GetName().Version;
埋め込んだバージョンは、exeファイルのプロパティから参照でき、プログラムからも取り出すことができます。
さらに、ビルドバージョンは2000年1月1日からの経過日数、リビジョンは0時からの秒数÷2で埋め込まれるため、バージョン番号からビルド日時を求めることができる、といったメリットがあります。
.NET時代でもアスタリスクを使ったバージョン付与は可能ですが、非推奨のプロジェクト設定「Deterministic」をFalse(出力の一意性を無効)にしなければならないうえ、同様の方法ではプロダクトバージョンには反映されず、プロパティから参照できなくなってしましました。(プログラムから取り出すことは可能)
つまり、とても中途半端になってしまったわけです。
プロジェクトのビルド前処理でアセンブリを更新する
そこでいろいろ調べた結果、プロジェクトファイル(.csproj)を編集してアセンブリ情報を更新する記述を行うことで自動的に任意のアセンブリ情報を更新できることが分かりました。
具体的には、下記XMLをプロジェクトファイル(.csproj)に挿入します。
<PropertyGroup> <MajorVersion>1</MajorVersion> <MinorVersion>0</MinorVersion> </PropertyGroup> <Target Name="UpdateVersion" BeforeTargets="BeforeBuild"> <PropertyGroup> <!-- Generate Version (Major.Minor.Build.Revision) Build=Days Rvision=Seconds/2 per oneday --> <BaseDate>2000-01-01</BaseDate> <CurrentDate>$([System.DateTime]::Now)</CurrentDate> <TicksPerDay>864000000000</TicksPerDay> <!-- Oneday Ticks --> <DaysSinceBaseDate>$([MSBuild]::Divide($([MSBuild]::Subtract($([System.DateTime]::Parse($(CurrentDate)).Ticks), $([System.DateTime]::Parse($(BaseDate)).Ticks))),$(TicksPerDay)))</DaysSinceBaseDate> <SecondsOfDay>$([System.DateTime]::Parse($(CurrentDate)).TimeOfDay.TotalSeconds)</SecondsOfDay> <RoundedSeconds>$([System.Math]::Round($(SecondsOfDay)))</RoundedSeconds> <Revision>$([MSBuild]::Divide($(RoundedSeconds), 2))</Revision> <VersionString>$(MajorVersion).$(MinorVersion).$(DaysSinceBaseDate).$(Revision)</VersionString> <AssemblyVersion>$(VersionString)</AssemblyVersion> <ProductVersion>$(VersionString)</ProductVersion> <InformationalVersion>$(VersionString)</InformationalVersion> </PropertyGroup> </Target>
この例ではアプリケーションの任意のメジャー、マイナーバージョンをMajorVersion、MinorVersionで指定することを想定しています。
BeforeTargets="BeforeBuild"がビルド前に行う処理であることを示し、AssemblyVersion、ProductVersion、InformationalVersionの部分が作り出したVersionStringを定義している箇所です。
バージョン取り出し、日時への変換コード例
using System.Diagnostics; using System.Reflection; var assembly = Assembly.GetExecutingAssembly(); // アセンブリのバージョン情報を取得 var version = assembly.GetName().Version; Debug.Assert(version != null); var dateTime = new DateTime(2000, 1, 1); dateTime = dateTime.AddDays(version.Build).AddSeconds(version.Revision * 2); Console.WriteLine($"アセンブリバージョン: {version}"); Console.WriteLine($"ビルド日時時刻 : {dateTime.ToString("yyyy-MM-dd HH:mm:ss")}");
VisualStudio2022、.NET8で動作確認しています。
出力結果例
プロパティ表示例