2

我正在使用一对未签名的第 3 方程序集库,其中包含我创建派生类的 Windows 控件和基本类型。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 事件,所以现在所有其他依赖程序集都会触发该事件,除了 sharedlibA 和 sharedlibB。它们仍然会导致 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

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

4

2 回答 2

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>
于 2012-10-09T20:20:12.243 回答
0

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

于 2012-10-09T17:49:09.143 回答