« Flas列挙体用汎用プロパティエディタ | トップページ | .NETでリソースにアクセスする »

2011年1月10日 (月)

バージョン情報の設定

.NETのアセンブリに対するバージョン情報を埋め込むには@ITの.NET TIPS アセンブリにバージョン情報を設定するには?でも紹介されていますが、当方で調査した結果等を加えた内容で、ここにまとめておきます。

バージョン情報の埋め込み

まず、バージョン情報を埋め込む場合、プロジェクト作成時に自動生成された AssemblyInfo.cs に雛形が作成されているので、ここのAssemblyXXX の項を埋めるのが一般的です。もっともC#2005だと、プロジェクトのプロパティ-アプリケーションタブのアセンブリ情報で表示されるアセンブリ情報ダイアログから入力する事も可能です。例えばに、左図の様なダイアログ内容で入力すると、AssemblyInfo.cs に自動的に反映され、以下の様になります。


using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Resources;

// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 
// アセンブリに関連付けられている情報を変更するには、
// これらの属性値を変更してください。
[assembly: AssemblyTitle("アセンブリのタイトル")]
[assembly: AssemblyDescription("アセンブリの説明")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("acha-ya")]
[assembly: AssemblyProduct("製品名")]
[assembly: AssemblyCopyright("Copyright (C) acha-ya 2011")]
[assembly: AssemblyTrademark("商標があれば入力")]
[assembly: AssemblyCulture("")]

// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントには 
// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 
// その型の ComVisible 属性を true に設定してください。
[assembly: ComVisible(false)]

// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です
[assembly: Guid("797a32d6-1a79-4480-a751-6bea0b0bc0b3")]

// アセンブリのバージョン情報は、以下の 4 つの値で構成されています:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0")]

なお、アセンブリ情報ダイアログのニュートラル言語の項は、AssemblyCulture に対応するかと思っていたら、NeutralResourcesLanguageAttribute に対応している様です。以下の様に日本(日本)に設定すると、AssemblyInfo.cs に以下の行が追加されました(AssemblyCulture は変化なし)。

AssemblyInfo.cs に追加された1行
[assembly: NeutralResourcesLanguageAttribute("ja-JP")]

また、各項目がバージョン情報のどれに該当するかを一覧形式でまとめておきます。

属性バージョン情報リソースアセンブリ情報ダイアログ
AssemblyTitle FileDescription タイトル
AssemblyDescription Comments 説明
AssemblyConfiguration
AssemblyCompany CompanyName 会社
AssemblyProduct ProductName 製品
AssemblyCopyright LegalCopyright 著作権
AssemblyTrademark LegalTrademarks 商標
AssemblyCulture
AssemblyInformationalVersion ProductVersion
AssemblyFileVersion FileVersion,ProductVersion アセンブリ バージョン
AssemblyVersion Assembly Version,
FileVersion,ProductVersion
ファイル バージョン

バージョン番号は、バージョン情報リソースとして使用される製品バージョンとファイルバージョンの2種類と、.NETアセンブリ用のバージョン情報の3種類が存在します。上表の通り、省略しても最終的に.NETアセンブリ用のバージョン番号が割り当てられるので、コンパイル後の実行ファイルには、製品バージョンとファイルバージョンがきちんと埋め込まれます。
なおアセンブリバージョンは、バージョン情報リソースとしても存在しており、その名前は、"Assembly Version"と付けられています。この事から、アンマネージドな実行ファイル上からも、Win32API VerQueryValue 関数により、アセンブリバージョンを取得可能だと思われます(未確認)。

バージョン情報リソースのバージョン番号における注意点

バージョン情報をリソーススクリプトから作成した経験を持っている方は御存知だと思いますが、実はバージョン情報リソースの製品バージョンとファイルバージョンは、固定情報部(VS_FIXEDFILEINFO)と可変情報部(StringFileInfo)にそれぞれ独立して存在しています。どちらも同じ情報から割り当てられるのですが、より忠実に反映する点で言えば、上表で示したのは、可変情報部側のバージョン番号に相当します。では、固定情報部の製品バージョンとファイルバージョンは、どの様に割り当てられるかというと、基本は同じなのですが、当記事入力例の様に"1.0"と入れると、固定情報部では、1.0.0.0とみなされます。これは固定情報部のデータが16bitの符号なし整数(C#ならushort相当)でバージョン番号各位(メジャー番号,マイナ番号,ビルド番号,リビジョン番号の4つ)が管理されているためでしょう。意地悪をして、

[assembly: AssemblyFileVersion("1.0.3a.ab")]
[assembly: AssemblyInformationalVersion("2.0.h5.3")]  // 最後の3は全角文字

と指定してみると、固定情報部の製品バージョンとファイルバージョンは、それぞれ1.0.3.0、2.0.0.0 となりました。もちろん、可変情報部の方は、指定した内容通りで埋め込まれました。下図は、リソースハッカーによるこの時のバージョン情報リソースの表示です。なおアセンブリ情報ダイアログからでは、この様な入力はエラーとなり、入力出来ない事からも、イレギュラルな書き方である事は間違いないと思います(ヘルプで AssemblyFileVersion のコンストラクタの説明にもこれに該当する記述があります。ただ AssemblyInformationalVersion の方はその手の記述が見受けられません。)

また、わざとオーバーフローする様な数を指定したり、マイナスの数値を指定したテストもしてみました。以下の様な指定をして、同じ様にリソースハッカーで表示した結果を示します。

[assembly: AssemblyFileVersion("2.0.65537.-1")]
[assembly: AssemblyInformationalVersion("3.0.65538.-2")]

単純に16ビット符号無し整数で型キャストされたものとして、扱われている様です。

ところで冒頭で紹介した@ITの記事では、エクスプローラのプロパティ画面最上段で表示されるファイルバージョンが、Win32ファイル・システム用のバージョン番号であり、AssemblyFileVersion で指定する内容が反映される様に書かれています。しかし、これは誤りではないですが厳密には不正確です。プロパティ画面最上段のファイルバージョンは、バージョン情報リソースの固定情報部のファイルバージョンを表示しており、これは AssemblyFileVersion (これを省略した場合は AssemblyVersion)の文字列を数値変換した値が表示されます(その結果、英字指定等は反映されない)。AssemblyFileVersion で入力された内容通りの表記は、可変情報部に埋め込まれるので下図の赤枠部に表示されます(Windows2000のプロパティ画面では、ファイルバージョンの項がないので、WindowsXPのプロパティ画面で示しています)。

バージョン番号の自動割り当てについて

バージョン番号の構成は、[メジャー番号].[マイナ番号].[ビルド番号].[リビジョン番号]となっています。
このうち、[ビルド番号]と[リビジョン番号]、または[リビジョン番号]のみを自動割り当てにする事が出来ます。それぞれ、以下の様な形で指定出来ます。

[assembly: AssemblyVersion("1.0.*")] ………[ビルド番号]と[リビジョン番号]を自動割り当て
[assembly: AssemblyVersion("1.0.0.*")] ………[リビジョン番号]のみ自動割り当て

C#2003で自動生成される AssemblyInfo.cs では、[assembly: AssemblyVersion("1.0.*")]と指定されており、自動割り当てが既定値になっています。しかし、C#2005では自動生成内容が[assembly: AssemblyVersion("1.0.0.0")]に変更されています。
変更された真の理由は知りませんが、C#2005からは署名がしやすくなっている事で、アセンブリに厳密名が付けやすくなっている事とか、Settings クラスといったアセンブリ・バージョン番号が関係するクラスが用意された事等が関係しているのではないかと思います。つまり、この様なものを利用する場合、コンパイルの度にバージョン番号がコロコロ変わる自動割り当ては都合が悪いので、無用なトラブル回避の為に既定の指定方法を変えたのではないでしょうか。

それから、AssemblyFileVersion や AssemblyInformationalVersion には、この * 指定による自動割り当ては出来ません。以下の様な * 指定を行なっても、他の文字と同じ扱いになります。このときのリソースハッカーで表示した結果を示します。

[assembly: AssemblyFileVersion("2.0.*")]
[assembly: AssemblyInformationalVersion("3.0.*")]

※VB.NETにおける自動割り当て
@IT の 旧@IT会議室 > Insider.NET > 「アセンブリのバージョン情報について」によると、VB.NETだと * 指定による自動割り当ては、初回のコンパイル時のみしか出来ない様です。

最後にバージョン番号構成表記について

FileVersionInfo クラスは、バージョン情報取得時に使用するクラスですが、こちらの説明では、バージョン番号の構成を、[メジャー番号].[マイナ番号].[ビルド番号].[プライベート パート番号]としており、リビジョン番号の表現がありません(プロパティからして FilePrivatePart, ProductPrivatePart となっています)。しかし実際は、このプライベート パート番号とリビジョン番号は、表現の違いだけで同じ事です。
同じ事が別の表現でされているのがややこしいですね。私自身、当初どっちの表現を使うかで混乱してしまいました。できたらどちらかの表現に統一して欲しいものです。

« Flas列挙体用汎用プロパティエディタ | トップページ | .NETでリソースにアクセスする »

覚え書き」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: バージョン情報の設定:

« Flas列挙体用汎用プロパティエディタ | トップページ | .NETでリソースにアクセスする »