应用程序尝试加载错误版本的程序集

时间:2012-10-09 17:32:10

标签: .net assemblies version

我正在使用一对未签名的第三方程序集库,其中包含我创建派生类的窗口控件和基本类型。 dll驻留在我的应用程序安装的子文件夹中。除了我的控制之外,具有相同名称但针对更高版本的.Net运行时构建的库的较新版本安装在与我的可执行文件相同的目录中。

这导致我的应用程序抛出BadImageFormatException:

  

无法加载文件或程序集'sharedlibA'[...]此程序集是   由比当前加载的运行时更新的运行时构建而不能   加载。

这是我正在使用的文件系统结构:

[MyappFolder]
   |--Myapp.exe
   |--sharedlibA.dll (wrong version)
   |--sharedlibB.dll (wrong version)
   |--bin
       |--sharedlibA.dll (need to use this)
       |--sharedlibB.dll (need to use this)

我一直在阅读不同的程序集加载上下文并创建一个单独的AppDomain,但这些似乎都不起作用。

修改

我已经从配置文件中删除了探测信息,正如Hans在下面建议并订阅了AssemblyResolve事件,所以现在所有其他依赖程序集都会触发sharedEibA和sharedlibB的事件EXCEPT。它们仍会导致BadImageFormatException。尽管发生了变化,看起来AppBase文件夹仍在探测中。

这是融合日志:

=== Pre-bind state information ===
LOG: User = ...
LOG: DisplayName = sharedlibA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=643d95c7ce242296
 (Fully-specified)
LOG: Appbase = file:///C:/[MyappFolder]
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\[MyappFolder]\Myapp.exe.Config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Post-policy reference: sharedlibA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=643d95c7ce242296
LOG: Attempting download of new URL file:///C:/[MyappFolder]/sharedlibA.DLL.
ERR: Failed to complete setup of assembly (hr = 0x8013101b). Probing terminated.

编辑#2

我已经解决了我的具体问题。回答如下。

2 个答案:

答案 0 :(得分:1)

我通过向应用程序配置文件添加<codeBase>元素来解决此问题,以指定每个dll的确切位置。显然这是有效的,因为在每次需要加载程序集时,在探测启发式搜索之前检查<codebase>

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="sharedlibA" culture="neutral" publicKeyToken="..." />
      <codeBase version="1.0.0.0" href="bin\sharedlibA.dll" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="sharedlibB" culture="neutral" publicKeyToken="..." />
      <codeBase version="1.0.0.0" href="bin\sharedlibB.dll" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

答案 1 :(得分:0)

这真的应该用“停止这样做!”来解决。一个非常具体的解决方法是删除.exe.config文件中的<probing>元素,以便CLR无法再找到DLL。并实现AppDomain.CurrentDomain.AssemblyResolve事件以返回受祝福的事件。