C#:无法从程序集中加载类型

Posted

技术标签:

【中文标题】C#:无法从程序集中加载类型【英文标题】:C#: Could not load types from assembly 【发布时间】:2012-05-05 02:13:29 【问题描述】:

将 Lucene.net 和 Lucene.net Contrib 添加到 C# MVC3 后,我在第一次成功运行后收到以下消息。收到此错误后,我需要完全擦除 C:\Users\Me\AppData\Local\Temp\Temporary ASP.NET 文件,然后才能再次运行该项目。

我尝试手动删除 Lucene 文件(包括我的项目中的引用),然后重新安装它们 - 无论是使用 NuGet 还是手动 - 但情况总是相同;项目运行一次后,我开始收到以下错误:

注意:Contrib.Regex 是 Lucene.net Contrib 的一部分。

Server Error in '/' Application.

Could not load types from assembly Contrib.Regex, Version=2.9.4.0, Culture=neutral, PublicKeyToken=85089178b9ac3181, errors:
Exception: System.IO.FileLoadException: Could not load file or assembly 'Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181'

=== Pre-bind state information ===
LOG: User = rcw7\Me
LOG: DisplayName = Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181
(Fully-specified)
LOG: Appbase = file:///C:/Development/Projects/Foobar/Foobar/
LOG: Initial PrivatePath = C:\Development\Projects\Foobar\Foobar\bin
Calling assembly : Contrib.Regex, Version=2.9.4.0, Culture=neutral, PublicKeyToken=85089178b9ac3181.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Development\Projects\Foobar\Foobar\web.config
LOG: Using host configuration file: C:\Users\Me\Documents\IISExpress\config\aspnet.config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181
LOG: Attempting download of new URL file:///C:/Users/Me/AppData/Local/Temp/Temporary ASP.NET Files/root/e9b4cfa4/edfa73f8/Lucene.Net.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Revision Number
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
Exception: System.IO.FileLoadException: Could not load file or assembly 'Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181'

此处的完整输出:http://pastebin.com/Vbu4VK7B

最初我认为这是我的开发环境本地的问题,但在重建项目并将其复制到我们的服务器后,我得到了同样的错误。

关于如何克服这个问题的任何建议? :-)

【问题讨论】:

【参考方案1】:

事实证明,DLL 地狱并不是由我自己干预配置和编译库引起的。这实际上是由于我新下载的 Lucene.NET 版本和与 Examine 捆绑在一起的有点过时的版本之间的冲突造成的,而后者又与 Umbraco 5 捆绑在一起。

显然,过时的、捆绑的 Lucene.NET 最终位于影子缓存(临时 ASP.NET 文件)中,因此在下一次编译或 IIS 重新启动后,执行会中断。清除影子缓存将允许一次成功执行。

奇怪的是,我无法在调试输出的任何地方找到任何暗示 Lucene.NET 版本过时的引用,无论是目录路径还是版本号。通过比较 Lucene.NET 的影子复制版本和我打算使用的版本的文件大小发现了这个问题。他们关闭了,所以我搜索了 Lucene.NET.dll 并在 Umbraco 树中找到了与 Examine 捆绑的那个(在 \App_Plugins\Examine 下)

快速的解决方案是简单地压缩检查插件,这样 Umbraco 就不会看到它。这让我没有检查插件,但我并没有使用它。

正确的解决方案可能是告诉应用程序它应该忽略以前版本的 Lucene.NET,但到目前为止我还没有运气。这是我添加到 web.config 中的内容:

<dependentAssembly>
    <assemblyIdentity name="Lucene.Net" publicKeyToken="85089178b9ac3181" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-2.9.4.1" newVersion="2.9.4.1" />
</dependentAssembly>

这似乎没有任何效果,过时的版本仍然在影子缓存中结束。我把这个问题移到这里:How do I make Umbraco 5 ignore the bundled (with Examine) Lucene.NET

感谢您的帮助和建议 - 它为我指明了正确的方向! :-)

【讨论】:

【参考方案2】:

这通常意味着您在 GAC 中的文件是不同的版本,而您的 bin 中的文件是另一个版本。所以你的应用程序指向一个版本,它正在寻找另一个版本。它变得越来越混乱。您要做的是卸载 Lucene.net。卸载后,查看 c:\windows\assembly 文件夹并确保其中没有 Lucene 文件。如果有,请右键单击并卸载。然后你可以重新安装。

【讨论】:

与应用程序的 bin 目录和 GAC 相比,在 c:\windows\assemblies 中查找的优先级是什么?我希望系统目录是最后的手段? 我认为 GAC 会覆盖任何其他位置。 C:\windows\assemblies GAC。它仅在引用不需要特定版本时覆盖,在这种情况下使用两者中较新的版本。 啊,抱歉,我指的是 GAC(c:\windows\assemblies)、我的本地卷影副本(ASP.NET 临时文件)和应用程序的 bin 目录的优先级。【参考方案3】:

manifest definition does not match 表示程序集的解析存在问题。 see this SO question

[编辑]

程序集从 GAC 加载,然后是应用程序中的 lib/bin 目录,然后是项目中通过 &lt;HintPath&gt; 指定的目录。检查你有没有

Specific Version = TrueCopy Local = True

在引用的属性窗口中。

应用程序中私有路径(lib/bin 目录)中的程序集是唯一会进行影子复制的程序集。可能 Contrib.Regex 正在被影子复制,而 Lucene.NET 核心没有。

[/edit]

您正在擦除的ASP.NET Temporary Files 下的目录是shadow-copy 目录。此程序集的复制方式可能存在问题,可能是您的域帐户的权限。您可以通过更改 shadowcopy 目录或完全关闭 shadowcopying 来测试此理论,如 here 所述:

您可以按照说明在 Application_Start 中更改此目录 https://***.com/a/2847495/151445

您可以在 web.config 中关闭卷影复制:

&lt;hostingEnvironment shadowCopyBinAssemblies="false" /&gt;

【讨论】:

我试图通过在 下的 web.config 中删除 行来关闭卷影复制,但我仍然在 shadow-copy 目录中获得 DLL? 只有在您的文件更新后,如果您在 ApplicationPool 中有一个现有的 AppDomain,这应该会发生。这是因为 IIS 缓存每个 AppDomain 的 web.config,如果一个 AppDomain 的缓存 web.config 具有较旧的设置,您更新的文件仍将被卷影复制。不过,新的 AppDomain 不应受此影响。我将重新启动 Visual Studio 和 IIS 以确保没有陈旧的 AppDomain 并查看它是否仍然发生。【参考方案4】:

您可以使用Fusion Log Viewer 来诊断此问题。它为您提供了加载失败的类型的完整详细信息,类似于您在此处报告的类型。希望这会有所帮助。

【讨论】:

我似乎无法让 Fusion Log Viewer 工作 - 尝试以管理员身份运行它,但似乎什么也没有出现,即使我的项目崩溃了。它在 IIS Express 下运行是否会有所不同? 请确保您通过“设置...”按钮启用了“日志设置”中的“启用所有绑定到磁盘”复选框。运行应用程序后执行“刷新”。让我知道这是否有帮助。 啊,现在可以工作了 - 必须选择“记录所有绑定到磁盘”并指定自定义日志路径,如 C:\tmp - 现在调查 :-)

以上是关于C#:无法从程序集中加载类型的主要内容,如果未能解决你的问题,请参考以下文章

C#反射实例学习及注意内容

C#“动态”无法访问在另一个程序集中声明的匿名类型的属性

未能从程序集中加载类

(转)详解C#中的反射

Oracle .Net ManagedDataAccess 错误:无法从程序集中加载类型“OracleInternal.Common.ConfigBaseClass”

C# - 无法从 ResourceManager 获取字符串(来自附属程序集)