这个问题涉及一个ASP.NET网站,最初是在VS 2005中开发的,现在是在VS 2008中开发的.
这个网站使用两个非托管的外部DLL,它们不是.NET,我没有编译它们的源代码,必须按原样使用它们.
这个网站在Visual Studio中运行良好,正确定位和访问这些外部DLL.但是,当网站发布在Web服务器(运行IIS6和ASP.NET 2.0)而不是开发PC时,它无法找到并访问这些外部DLL,我收到以下错误:
Unable to load DLL 'XYZ.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
外部DLL位于网站的bin目录中,以及包装它们的托管DLL以及网站的所有其他DLL.
搜索此问题表明,许多其他人似乎在从ASP.NET网站访问外部非.NET DLL时遇到同样的问题,但我找不到可行的解决方案.
我尝试过以下方法:
运行DEPENDS来检查依赖关系以确定前三个是在路径中的System32目录中,最后一个是在.NET 2框架中.
我将两个DLL及其依赖项放在System32中并重新启动服务器,但网站仍然无法加载这些外部DLL.
将ASPNET,IIS_WPG和IUSR(对于该服务器)的完全权限授予网站bin目录并重新启动,但网站仍然无法加载这些外部DLL.
将外部DLL作为现有项添加到项目中,并将其"复制到输出"属性设置为"始终复制",并且网站仍然无法找到DLL.
还将其"Build Action"属性设置为"Embedded resource",网站仍无法找到DLL.
任何有关此问题的帮助将不胜感激!
发生这种情况是因为托管dll将阴影复制到.NET Framework目录下的临时位置.有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/ms366723.aspx.
不幸的是,非托管dll不会被复制,并且ASP.NET进程在需要加载它们时将无法找到它们.
一个简单的解决方案是将非托管dll放在系统路径中的目录中(在命令行中键入"path"以查看计算机上的路径),以便ASP.NET进程可以找到它们.System32目录始终在路径中,因此将非托管dll放在那里总是有效,但我建议在路径中添加一些其他文件夹,然后在那里添加dll以防止污染System32目录.这种方法的一个很大的缺点是你必须为应用程序的每个版本重命名非托管dll,你可以快速拥有自己的dll地狱.
作为将dll放在已经在路径中的文件夹(如system32)的替代方法,您可以使用以下代码更改进程中的路径值
System.Environment.SetEnvironmentVariable("Path", searchPath + ";" + oldPath)
然后,当LoadLibrary尝试查找非托管DLL时,它还将扫描searchPath.这可能比在System32或其他文件夹中制作混乱更可取.
尝试将dll放在\ System32\Inetsrv目录中.这是Windows Server上IIS的工作目录.
如果这不起作用,请尝试将dll放在System32目录中,并将依赖项文件放在Inetsrv目录中.
添加到Matt的答案,这是我最终为64位服务器2003/IIS 6工作的东西:
确保你的dlls/asp.net版本相同(32/64位)
将非托管dll放在inetsrv目录中(请注意,在64位窗口中,这是在syswow64下,即使创建了sys32/inetsrv目录)
将托管dll保留在/ bin中
确保两组dll都具有读/执行权限
看看FileMon或ProcMon,并过滤麻烦的DLL的名称.这将显示搜索DLL时扫描的目录以及您可能遇到的任何权限问题.