C++ ときどき ごはん、わりとてぃーぶれいく☆

USAGI.NETWORKのなかのひとのブログ。主にC++。

C#: ビルド番号の自動採番の有効化と Properties.Settings.Default の Upgrade トリックの必要について

遠いむかしの記憶、 C# というか Visual Studio のプロジェクト管理システムにはバージョン番号の一部を自動採番する便利な機能があった、ような気がした。実際に執筆時点で現行製品の VS2017 で作った C# のプロジェクトの AssemblyInfo.cs にも次のコメントが自動的に書かれた状態で生成されていた。

// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]

ビルド番号を自動採番にしておくと頻繁な開発とα版、β版の試供などを行うプロジェクトでは何かと便利が良い。そこで、

// 実際に現行の VS2017 で C# プロジェクトを作成し、 AssemblyInfo.cs を
// コメントに従って自動採番ひゃっほーぃ!してみるのだが…
[assembly: AssemblyVersion("0.0.0.*")]

このようなワイルドカードバージョンを定義すると VS2017 は自動生成されていたコメントとは裏腹に 嫌な気配のする赤波線 を引いてエラーを報告し、プロジェクトはビルド不能に陥ってしまう。

Error CS8357 The specified version string contains wildcards, which are not compatible with determinism. Either remove wildcards from the version string, or disable determinism for this compilation

この問題はググるナウい C#er たちが解決方法を教えてくれていた😋

<!-- your-project.csproj を適当なテキストエディターで直接開いていじる -->
<Project ... 略 ... >
  <PropertyGroup>
    ... 略 ...
    <!-- ↓これを true から false へ変える -->
    <Deterministic>false</Deterministic>

さて、それでバージョン番号に自動採番を有効化してみると、今度はソースの微小な変更であれ再ビルドが発生するとバージョン番号が変わるため、 Properties.Settings.Default によりユーザーごとに保存されるはずの設定値がすべて再ビルドを挟む度にプロジェクトの Settings.settings の初期値へと毎度戻ってしまう問題に遭遇した。

この問題の解決方法は stackoverflow でベテラン C#er の Markus Olsson がベストな答えを投稿してくれていた:

  1. Settings.settinfsUpgradeRequiredbool で追加し、既定値を True にしておく。
  2. 設定値をアプリが使う前(例えばメインの Window クラスの構築子とか)に UpgradeRequired をチェックして Upgrade メソッドを呼んで Save もしてしまう。

なるほど😃

なお、この設定値の問題は何れしばらく後にリリース版のアプリのバージョン番号がアップグレードされる際にも発生したであろうので、さっさと気づけて良かったとも思える。