【问题标题】:Application attempts to load wrong version of assembly应用程序尝试加载错误版本的程序集
【发布时间】:2012-10-09 17:32:09
【问题描述】:

我正在使用一对未签名的第 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

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

【问题讨论】:

    标签: .net assemblies version


    【解决方案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>
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 哦,对了,它仍然可以找到DLL,因为它与EXE在同一目录中。好吧,您只能“停止这样做!”
      猜你喜欢
      • 2020-10-23
      • 2014-07-27
      • 1970-01-01
      • 2012-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多