アセンブリ参照の「特定のバージョン」プロパティは、Visual Studioでどの程度正確に機能しますか?


155

今日、私はVisual Studio 2010のアセンブリ参照の「特定のバージョン」プロパティを詳しく調べました。予期しない結果を伴ういくつかの実験の後、プロパティがどのように機能するかについて可能な限り学ぶことに着手しました。SOでさえ、それは私には見えますが、すべての答えを持っているわけではありません。

アセンブリ参照の「特定のバージョン」プロパティは、Visual Studioでどのよう機能しますか?

回答:


255

これはコンパイル時のプロパティです!

知っておくべき最も重要なことの1つは、「特定のバージョン」は、実行はなくコンパイル時に有効になるプロパティであることです。

それは何についてですか?

プロジェクトがビルドされるとき、ビルドシステムが使用する必要のある物理アセンブリを見つけるために、プロジェクトのアセンブリ参照を解決する必要があります。「特定のバージョン」チェックが実行された場合(「「特定のバージョン」がチェックされるのはいつですか?」のセクションを参照)、アセンブリ解決プロセスの結果に影響します。

  • ビルドシステムは、潜在的に使用できる物理アセンブリを見つけます
  • ビルドシステムは、物理アセンブリのバージョンを、アセンブリ参照用の.csprojファイルに保存されているアセンブリバージョンと比較します。
  • 2つのアセンブリバージョンがまったく同じ場合、解決プロセスは成功し、見つかった物理アセンブリがビルドに使用されます
  • 2つのアセンブリバージョンが一致しない場合、物理アセンブリは破棄され、次の潜在的なアセンブリを見つけることにより解決プロセスが続行されます。
  • 潜在的な物理アセンブリが見つからない場合、解決プロセスは失敗します。これにより、参照を解決できなかったことを示すコンパイラ警告(MSB3245の警告)が表示されます。
  • 興味深いことに、ビルドは続行されます!コードにアセンブリへの実際の参照がない場合、ビルドは成功します(前述の警告が表示されます)。コードに参照がある場合、コードが不明な型または名前空間を使用しているかのように見えるエラーでビルドが失敗します。ビルドが実際に失敗した唯一の兆候は、MSB3245の警告です。

アセンブリが解決される順序

アセンブリ解決プロセスが潜在的なアセンブリを見つける順序は次のように見えます。

  1. <HintPath>.csprojファイルの要素によって参照されるアセンブリ
  2. プロジェクトの出力パス
  3. GAC

アセンブリの複数のバージョンがGACに存在する場合、解決プロセスは最初に最も高いバージョンのアセンブリへの解決を試みます。これは、「特定のバージョン」チェックが行われていない場合にのみ重要です。

「特定のバージョン」はいつチェックされますか?

Visual Studioは、.csprojファイルにある2つの情報に基づいて「特定のバージョン」チェックを実行するかどうかを決定します。

  • <SpecificVersion>要素の有無とその値(存在する場合)
  • アセンブリ参照でのバージョン情報の有無

これは、バージョン情報を含む一般的なアセンブリ参照は次のようになります。

<Reference Include="Foo, Version=1.2.3.4, Culture=neutral, processorArchitecture=MSIL">
  <SpecificVersion>True</SpecificVersion>
  <HintPath>..\..\Bar\Foo.dll</HintPath>
</Reference>

そして、これはバージョン情報なしでアセンブリ参照がどのように見えるかです:

<Reference Include="Foo">
[...]

次の表は、「特定のバージョン」チェックが実行される場合と実行されない場合を示しています。

                            |     Version information
                            |  Present       Not present
----------------------------+------------------------------
<SpecificVersion>           |
- Present, has value True   |    Yes (1)        Yes (check always fails) (2)
- Present, has value False  |    No  (3)        No (4)
- Not present               |    Yes (5)        No (6)

ここで意外なのは<SpecificVersion>、バージョン情報とバージョン情報の両方が存在しない場合(ケース6)、チェックが実行されないことです。チェックが実行され、常に失敗することを期待していました(ケース2と同じ)<SpecificVersion>。これは、テストを行ったVisual Studio 2010の癖かもしれません。

Visual Studio UIでアセンブリ参照のプロパティを調べるとき(参照を選択してF4を押す)、「特定のバージョン」プロパティに表示される値は、Visual Studioが「特定のバージョン」を実行するかどうかを示します小切手。ケース6の場合、UIには「True」と表示されますが、<SpecificVersion>要素は.csprojファイルには存在しません。

「ローカルコピー」への副作用

「ローカルのコピー」プロパティが「True」に設定されているが、「特定のバージョン」チェックのためにアセンブリ解決プロセスが失敗した場合、アセンブリはコピーされません。

参考資料


詳細をありがとう。確認できますか?アセンブリバージョンの確認は、厳密な名前のアセンブリに対してのみ行われます。そうですか?また、アセンブリのバージョンの確認について話すとき、参照されたアセンブリの名前を比較することによって行われますか?(厳密な名前のアセンブリの場合、その名前はバージョン情報が含まれているため、個別のバージョンフィールドがチェックされるようなものではありませんか?)
Gavin Hope

2
@GavinHope質問1:いいえ、バージョンチェックは厳密な名前に限定されていません。主にアセンブリ名にバージョンを含めることができるが、厳密な名前ではない(たとえば、PublicKeyToken=パーツが欠落している場合)ためです。また、私の投稿の最後の方で表を確認するVersion=と、.csprojのアセンブリ名にパーツが欠落している場合でも、バージョンチェックが行われる可能性があることがわかります。質問2:アセンブリ名が比較に使用されていると思います、はい。他の情報源は知りません。
herzbube 2016

「ケース6の場合、UIには「True」が表示されますが、<SpecificVersion>要素は.csprojファイルに存在しません。」-デフォルト値はTrueのようです。UIの特定のバージョンをTrueに切り替えた後、<SpecificVersion>タグは完全に省略されました。以前はFalseの値でした。
samis

@herzbube-Visual Studioの[プロジェクトのプロパティ]ウィンドウでの「特定のバージョン」の意味は、ここで言うこととは逆になっていると思います(これは期待するものとは逆です)。Visual Studioは、「特定のバージョン」の値(trueまたはfalse)は、「このアセンブリが、アセンブリ解決のマルチターゲットルールに関係なく解決できるかどうかを示す」と述べています。
N73k

35

参照を追加すると、Visual Studioはアセンブリの[AssemblyVersion]をプロジェクトファイルに記録します。これは重要。たとえば、1年後にバグ修正を作成する場合、完全に同じバージョンのリファレンスを使用してプロジェクトを再ビルドして、それが真のドロップインであることを確認する必要があります。参照アセンブリが変更されていると、エラーが発生します。

しかし、それが常に望ましいとは限りません。一部のプログラマーは、アセンブリバージョンを自動的にインクリメントさせ、再ビルドするたびに新しいバージョンを生成します。アセンブリのパブリックインターフェイスは変更されていませんが。Nugetを使用してプロジェクトを構成してライブラリを取得し、新しいリリースが利用可能になったときに自動的にライブラリを更新するようにする人もいます。特定のバージョンプロパティをFalseに設定して、コンパイルエラーを抑制します。

結果を理解することは非常に重要です。事故を回避するには、プログラムのビルド全体を再デプロイする必要があります。実行時のバージョンの不一致はプログラムをクラッシュさせ、<bindingRedirect>危険な.configファイルでのみ抑制できます。


2
「特定のバージョン」が重要である理由の情報をありがとう、これは私が私の答えでカバーしている純粋に機械的な側面の良い仲間です。
herzbube 14年

@Hans Passant-あなたの最後の段落はSpecificVersionのTrueまたはFalseで有効ですか?あなたがそれをtrueに設定したとき、これらは結果だと思います。
GreenEyedAndy 2016年

1
SpecificVersionは、アプリのビルドにのみ適用されます。実行時に、CLRは常に参照アセンブリのバージョン番号との完全一致を要求します。ビルド時に新しいバージョンを使用した場合は、実行時にもその新しいバージョンである必要があります。
ハンス・パッサント2016年

1
VS2013と.Net 4.5.1に注意してくださいAutoGenerateBindingRedirects特定のバージョンを使用するように指示したにもかかわらず、それらはDLLバインディングを新しいバージョンにリダイレクトする可能性があります
Dennis Kuypers

1
@HansPassant [AssemblyVersion]アセンブリが厳密な名前で署名されていない場合、CLRは考慮しないと思いました。
tm1 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.