8

このコードを使用して、実行時に 2 つのサブフォルダーから 2 つのアセンブリを読み込む単純なアプリケーションがあります。

Assembly.Load("A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
Assembly.Load("B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");

ディレクトリ構造は次のとおりです。
ここに画像の説明を入力
したがって、予想されるロードは次のようになります。

TheApp.exe -> A.dll -> C.dll (version 2.0.0.0)
           -> B.dll -> C.dll (version 1.0.0.0)

C.dllは署名されているため、両方のバージョンを並べてロードする必要があることに注意してください。

アプリケーションが適切な場所からアセンブリをロードしていることを確認するために、アプリケーション構成ファイルに次を追加しました。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="B;A" />
    </assemblyBinding>
  </runtime>
</configuration>

問題は、起動するたびにアプリケーションがクラッシュし、次のメッセージが表示されることです。

=== Pre-bind state information ===
LOG: User = ...
LOG: DisplayName = C, Version=2.0.0.0, Culture=neutral, PublicKeyToken=93a02044a09d059a
 (Fully-specified)
LOG: Appbase = file:///D:/Temp/TheApp/bin/Debug/Test/
LOG: Initial PrivatePath = NULL
Calling assembly : A, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: D:\Temp\TheApp\bin\Debug\Test\TheApp.exe.Config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Post-policy reference: C, Version=2.0.0.0, Culture=neutral, PublicKeyToken=93a02044a09d059a
LOG: Attempting download of new URL file:///D:/Temp/TheApp/bin/Debug/Test/C.DLL.
LOG: Attempting download of new URL file:///D:/Temp/TheApp/bin/Debug/Test/C/C.DLL.
LOG: Attempting download of new URL file:///D:/Temp/TheApp/bin/Debug/Test/B/C.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Major Version
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

質問: ランタイムが "B" フォルダーのみを参照するのはなぜですか? A フォルダー内の共有アセンブリの正しいバージョンを探し続けないのはなぜですか?

EDIT1:以下のようにタグを追加しました<codeBase>。設定ファイルに次のものが含まれていることがわかっています。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <probing privatePath="B;A" />
    </assemblyBinding>
    <dependentAssembly>
       <assemblyIdentity name="C" publicKeyToken="93a02044a09d059a" /> 
       <codeBase version="1.0.0.0" href="B/C.dll"/>
       <codeBase version="2.0.0.0" href="A/C.dll"/>
    </dependentAssembly>
  </runtime>
</configuration>

それでも問題は解決しません!

4

1 に答える 1

7

問題に直接対処する調査に関するこのMSDN ページのメモを参照してください。

ディレクトリにアセンブリの複数のバージョンがあり、そのアセンブリの特定のバージョンを参照する場合は、要素の属性の<codeBase>代わりに要素を使用する必要があります。この要素を使用すると、ランタイムは、参照されている単純なアセンブリ名と一致するアセンブリが最初に見つかったときに、それが正確に一致するかどうかに関係なく、プローブを停止します。正しく一致する場合、そのアセンブリが使用されます。正しく一致しない場合、プローブは停止し、バインドは失敗します。privatePath<probing><probing>

ランタイムは 2.0.0.0 バージョンを探しますが、1.0.0.0 バージョンを見つけて検索を停止します。

最終的な解決策は、構成ファイルを次のように変更することです。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
     <probing privatePath="B;A" />
     <dependentAssembly>
       <assemblyIdentity name="C" publicKeyToken="93a02044a09d059a" /> 
       <codeBase version="1.0.0.0" href="B/C.dll"/>
       <codeBase version="2.0.0.0" href="A/C.dll"/>
     </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
于 2013-02-19T08:30:01.173 に答える