TIPs of C# – #002. WPFのバージョン設定

前提条件

OS:Windows 11 Pro
Visual Studio:2022 v17.6.5
Project:WPFアプリケーション

バージョン設定

自分の中の位置づけ

自分がソフトウェアを開発する際には、各フェーズ(機能追加や変更)でバージョンを設定しています。
バージョンと機能・変更が紐づけられていれば、『✕✕が出来ない』や『〇〇の不具合がある』と報告があった場合、そのバージョンを調べて古ければ、『バージョンx.x以上で修正されています』と回答できますし、未知の不具合や以前まで発生していなかった不具合が発生した際に、どのバージョンからその不具合から発生しているか調べる事で、どのコード変更が不具合の要因かを特定出来るためです。

あまり細かくバージョン付けしすぎるのもどうかとは思いますが、少なくともGITやSubVersionなどへのコミット時には別のバージョンを付ける様にはしています。

WPFアプリの開発でもそうしようと思っていたら躓いたので、バージョン設定に関する情報をまとめておきます。

WPFアプリのプロパティ

Visual Studioのプロジェクトのプロパティを表示すると下記の様になっています。

.NET Frameworkばかりに慣れていると、少し面喰います。.NET Frameworkアプリケーションのプロパティの「アセンブリ情報」ボタンもないですね…。

「パッケージ」辺りにバージョンなどの情報がありますが、「Nuget」などの単語が出てきます。『なぜ、アプリを作るのにNugetが関連するのか…?』と混乱しますが、Nugetパッケージも同時に作れ、バージョンなどの情報も共有する仕組みの様です。

しかし、ほとんどの項目で変数『$(xxxx)』を参照にしているようですが、プロジェクト全体にGrepを掛けても引っかかりません…。

WPFアプリのバージョン設定方法の情報がない?

ネットで検索しても、古い情報だったり、そもそも欲しい情報にヒットしなかったり…

あまりにも基本的すぎる情報なので、わざわざ公開するようなものではない??

でも、自分はその情報が欲しかった…。


WPFアプリでのバージョン設定

以下では製品バージョンを『0.1.0.0』、ファイルバージョンを『2.0.0』に設定する方法を示します。

設定方法① バージョンの直接入力

設定手順

パッケージバージョンに変数『$(VersionPrefix)』が入力されていますが、それは無視して、設定したいバージョンを直接入力します。

プロジェクトをビルドして、エクスプローラーで作成されたEXEのプロパティを確認すると以下の様になります。

確かにバージョンは入力した値になっています。

デメリット

直接入力は簡単ではありますが、ファイルバージョンと製品バージョンが一緒になってしまい、分けたい時には使えません。

(修正:2023/08/07)
上記の記述は誤りでした。というか「パッケージバージョン」を指定した場合です。
プロパティの下の方にちゃんと、アセンブリバージョン・ファイルバージョンの項目がありましたね…。お恥ずかしい…。

また、パッケージバージョンの左の歯車アイコンから「プロパティを規定値にリセットする」を選ぶと、変数『$(VersionPrefix)』に戻り、値も「1.0.0」に戻ってしまいます。

設定方法② プロジェクトファイルの編集による設定

設定手順

ソリューションエクスプローラーでプロジェクトを選択し右クリックメニューから「プロジェクトファイルの編集」を選択します。

プロジェクトファイル(*.cproj)の内容(XML形式)が表示されます。

製品バージョンの設定

製品バージョンの設定方法は2種類あります。

① Versionタグで指定

<PropertyGroup>タグの中に<Version>タグを追加して、そこに設定したいバージョンを設定します。

一応、プロジェクトのプロパティを確認すると、ちゃんと反映されています。

※Versionタグで指定すると、直接入力した場合とほぼ同じになります。

②VersionPrefixタグとVersionSuffixタグで指定

<PropertyGroup>タグの中に<Version>タグを指定しないで、<VersionPrefix>タグと<VersionSuffix>タグを追加して、そこに設定したいバージョンを設定します。

「VersionPrefix」と言う名前は元々のプロパティで表示されていたものです。ユーザーが指定しないと「1.0.0」と言うデフォルト値が適用されるようです。

こちらもプロジェクトのプロパティを確認すると、ちゃんと反映されています。(プロパティを開きなおさないと表示がうまく反映されない場合もあります)

※VersionPrefixで指定すると「既定値にリセットする」が選べなくなります。

「VersionSuffix」(接尾語)は必須ではなく、指定は不要ですが、バージョンにα版、β版、RC版などを示したい時に「alpha」などを指定すると、VersionPrefixの値を繋げられ、「0.1.0.0-alpha」の様なバージョンにする事が出来ます。

ファイルバージョンの設定

<PropertyGroup>タグの中に<FileVersion>タグを追加して、そこに設定したいバージョンを設定します。

こちらは、プロパティでは表示項目がそもそもないので、確認はできません。

プロジェクトをビルドして、エクスプローラーで作成されたEXEのプロパティを確認すると以下の様になります。

製品バージョン、ファイルバージョンが指定通りに設定できています。

(ファイルバージョンは4桁目(リビジョン)も付け加えられていますが…)

デメリット

製品バージョンをVersionタグで指定した場合には、パッケージバージョンの左の歯車アイコンから「プロパティを規定値にリセットする」を選ぶと、変数『$(VersionPrefix)』に戻り、値も「1.0.0」に戻ってしまいます。

プロジェクトファイル(*.cproj)を直接入力すると言うのは少しわかりにくく(公式ドキュメントも少ないですし…)、また、タグ名を間違えるとプロジェクトが読み込めなくなる場合もあります。その場合はテキストエディタで修正する必要があるでしょう。

設定方法③ AssemblyInfo.csの編集による設定

※個人的には最初これを思いついたのですが、なぜかうまく行かず苦労しました…。

設定手順

プロジェクト内のAssemblyInfo.csを開いて、AssemblyVersion、AssemblyInformationVersion、AssemblyFileVersionを追加し、バージョンを指定します。

ただ、このままビルドするとエラーが発生します…。

デフォルトでは、アセンブリ情報は自動でコード生成されるため、AssemblyInfo.csで追加したパラメータと重複してしまうようです。

これを回避するために、プロパティの中の「アセンブリ情報の生成」のチェックボックスを外します。

これでビルドが通る様になるので、ビルドして、EXEのプロパティを確認してみます。

製品バージョン、ファイルバージョンが指定通りに設定できています。

AssemblyInformationVersionがないと、「製品バージョン」の項目が「2.0.0」となります…

デメリット

この方法は、.NET Frameworkのやり方には近いですが、プロパティ画面の情報を整合性が取れない点が問題になるかと思います。

どの設定方法が良いか?

基本的にはどの方法でも良いかと思いますが、複数の方法をごっちゃにするのだけはやめた方が良いでしょう。

個人的には、Visual StudioのUIとの整合性を考えれば、『設定方法② プロジェクトファイルの編集による設定』が良いのかと思いますが、会社・組織に所属しているのであれば、その方針に従うべきでしょう。(コーディング規約と同じ)

(追記)
『設定方法①バージョンの直接入力』がVisual Studioとしては正式な方法の様に思えてきました。入力した値はプロジェクトファイルのPropertyGroupの対応するアイテムが自動的に追記されていく事や、情報の少ないファイル操作が正式とは思えないので、そうなんだろうなぁと…。にしても情報が少ない…。

補足

バージョン以外のタグ

設定方法② プロジェクトファイルの編集による設定』でバージョン以外の情報を設定するためのタグは以下になります。

タグ内容
Version製品バージョン
VersionPrefix製品バージョンの前半(”1.0.0″の様な数字の部分)
VersionSuffix製品バージョンの接尾語(”alpha”, “beta”, “rc”など)
FileVersionファイルバージョン
AssemblyName出力ファイル名(拡張子なし)、パッケージID。変更不要
Product製品名
Titleパッケージタイトル(Nuget用?)
Authors作成者
Company会社名
Copyright著作権表示
Description説明

コードからのアクセス

設定した値をコードから取得するには、下記の様なコードで行います。

string fullPath = Assembly.GetExecutingAssembly().Location;
FileVersionInfo info = FileVersionInfo.GetVersionInfo(fullPath);
// infoのプロパティからアクセスする
…

FileVersionInfoのプロパティとアクセスできる情報は下記になります(一部)

プロパティ内容対応するタグ
ProductVersion製品バージョンVersion, VersionPrefix,VersionSuffix
FileVersionファイルバージョンFileVersion
ProductName製品名Product
Company会社名Company
LegalCopyright著作権表示Copyright
Comments説明Description