8

我有一个简单的应用程序,它在运行时通过这段代码从 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 回答