为什么重命名dll扩展(即ell到dllold)会在运行时导致FileNotFound异常?

时间:2015-10-28 00:39:16

标签: c# asp.net .net dll runtime-error

在某些时候,我们的某个网站上的开发人员必须手动更新生产dll,我们将其称为“MyLibrary.dll”。在这样做时,他们将旧的dll文件扩展名更改为“dllold”。加载此站点后,我们收到System.IO.FileNotFoundException错误,表示Could not load file or assembly 'MyLibrary.dllold' or one of its dependencies. The system cannot find the file specified.我们收到此错误,即使“MyLibrary.dll”和“MyLibrary.dllold”都在正确的目录中。只有在删除此“dllold”文件或完全删除扩展名的“dll”部分(即MyLibrary.old)后,我们才能加载该网站。

所以我想知道为什么会发生这种情况?几乎看起来.NET框架的任何部分在运行时拉入dll只查找“dll”并且之后不关心任何事情,但这无法解释为什么它总是抓住“.dllold”库而不是工作“.dll”库。

作为参考,我们使用的是.NET 4.0和ASP.NET 4.6版。

2 个答案:

答案 0 :(得分:4)

当ASP.Net项目加载时,它将尝试加载应用程序bin文件夹中的所有DLL,它通过调用名为LoadAllAssembliesFromAppDomainBinDirectory的内部方法来完成此操作。在该方法的内部,使用DirectortInfo.GetFiles(string)方法检索DLL,模式为*.dll。这符合.dllold,文档证实:

  

在searchPattern中使用星号通配符时(例如,“ .txt”),匹配行为会根据指定文件扩展名的长度而有所不同。具有正好三个字符的文件扩展名的searchPattern将返回扩展名为三个或更多字符的文件,其中前三个字符与searchPattern中指定的文件扩展名匹配。文件扩展名为一个,两个或三个以上字符的searchPattern仅返回扩展名与searchPattern中指定的文件扩展名完全匹配的文件。使用问号通配符时,此方法仅返回与指定文件扩展名匹配的文件。例如,给定目录中的两个文件“file1.txt”和“file1.txtother”,搜索模式“file?.txt”仅返回第一个文件,而搜索模式为“file ”。 txt“返回两个文件。

在程序集加载过程的其他地方,假定文件名需要.dll后缀,这是一个不存在的文件,因此会引发您看到的异常。

所以这个故事的寓意是:如果你需要停止加载DLL,从你的bin文件夹中删除,或者你必须把它留在那里,给它一个后缀不会得到匹配。

答案 1 :(得分:1)

此外,根据对DLL所做的更改,如果两个副本都在bin文件夹中,则最终会加载两个具有相同名称空间的DLL。这可能会导致应用程序无法正常运行的其他问题。与其他装载ON DEMAND的.NET应用程序不同,ASP.NET在启动时加载所有DLL。