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

12

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

我尝试手动删除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

一开始我以为这是我的开发环境的问题,但是在重建并将项目复制到我们的服务器后,我遇到了同样的错误。

有什么建议可以解决这个问题吗?:-)

4个回答

7
事实证明,DLL地狱并不是由于我自己在配置和编译库方面的干预造成的。实际上,这是由我新下载的Lucene.NET版本与Examine捆绑的有点过时的版本之间发生冲突导致的,而Examine又与Umbraco 5捆绑在一起。
显然,过时的捆绑Lucene.NET最终被存储在阴影缓存(临时ASP.NET文件)中,所以在下一次编译或IIS重启后,执行会出现错误。清除阴影缓存将允许成功执行一次。
奇怪的是,在调试输出中,我找不到任何提示过时版本的Lucene.NET的引用,无论是目录路径还是版本号。通过比较阴影复制版本的Lucene.NET和我想使用的版本的文件大小,发现它们不同,因此我搜索了Lucene.NET.dll,并在Umbraco树(位于\ App_Plugins \ Examine下)中找到了与Examine捆绑的那个版本。
快速解决方案是简单地压缩Examine插件,这样Umbraco就看不到它了。这使我没有使用Examine插件,但我也没有使用它。
正确的解决方案可能是告诉应用程序应该忽略先前版本的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>

这似乎没有任何效果,而过时的版本仍然出现在阴影缓存中。我已将此问题移至此处:如何使Umbraco 5忽略与Examine捆绑(使用Lucene.NET)

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


3

通常这意味着您的GAC中有不同版本的文件,而bin中的文件是另一个版本。因此,您的应用程序指向一个版本,但实际上找到了另一个版本,导致混淆。您需要做的是卸载Lucene.net。卸载后,请查看c:\ windows \ assembly文件夹,确保其中没有Lucene文件。如果有,在其上右键单击并卸载。然后您可以重新安装。


查找c:\windows\assemblies的优先级如何与应用程序的bin目录和GAC相比?我期望系统目录是最后的选择? - Saustrup
我认为GAC会覆盖任何其他位置。 - Alex Mendez
1
C:\windows\assemblies 就是 GAC。只有在引用不需要特定版本时才会覆盖,此时会使用两者中较新的版本。 - Joseph Yaduvanshi
啊,抱歉,我指的是GAC(c:\ windows \ assemblies)的优先级,我的本地影子副本(ASP.NET临时文件)和应用程序的bin目录。 - Saustrup

3
manifest definition does not match的意思是程序集解析存在问题。具体请参考此SO问题[编辑] 程序集首先从GAC中加载,然后从应用程序的lib/bin目录中加载,最后从项目中指定的<HintPath>目录中加载。请检查您的引用属性窗口中是否设置了Specific Version=TrueCopy Local=True
应用程序内部私有路径(lib/bin目录)中的程序集是唯一会进行影像复制(shadow-copy)的。 Contrib.Regex可能在被影像复制,而Lucene.NET核心则没有被复制。 [/编辑] 您要清除的ASP.NET Temporary Files目录是一个影像复制目录。这个程序集的复制方式可能存在问题,这可能涉及到您的域帐户权限。在此处可以找到更改影像复制目录或完全关闭影像复制以测试此理论的方法:

您可以按照此处中所述,在Application_Start中更改此目录。

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

<hostingEnvironment shadowCopyBinAssemblies="false" />


我尝试通过在<system.web>下的web.config中删除<hostingEnvironment>行来关闭影子复制,但我仍然在影子复制目录中得到DLL文件? - Saustrup
只有在应用程序池中存在现有的AppDomain时,才会发生这种情况,一旦您的文件已更新。这是因为IIS每个AppDomain缓存web.config,如果一个AppDomain的缓存web.config具有较旧的设置,则您的更新文件仍将被影子复制。但新的AppDomain不应受此影响。我建议重新启动Visual Studio和IIS,以确保没有陈旧的AppDomains,并查看是否仍然发生此问题。 - Joseph Yaduvanshi

2
您可以使用Fusion Log Viewer来诊断这些问题。它会提供与您在此报告中类似的加载失败类型的详细信息。希望这能帮到您。

我似乎无法让Fusion日志查看器正常工作 - 尝试以管理员身份运行它,但即使我的项目崩溃时也似乎没有任何显示。它在IIS Express下运行会有任何影响吗? - Saustrup
请确保您通过“设置…”按钮在“日志设置”中启用了“将所有绑定保存到磁盘”复选框。在运行应用程序后,请执行“刷新”。如果有帮助,请告诉我。 - Cinchoo
啊,现在搞定了 - 必须选择“将所有绑定记录到磁盘”并指定自定义日志路径,例如C:\ tmp - 现在正在调查 :-) - Saustrup

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接