无法从 x64/x86 加载 DLL 'SQLite.Interop.dll' 但能够加载 System.Data.SQLite.dll 旁边的那个
Unable to load DLL 'SQLite.Interop.dll' from x64/x86 but is able to load the one alongside System.Data.SQLite.dll
我 运行 遇到了这个奇怪的问题。在我的 WCF 项目中,我引用了一个 class 库,它使用 SQLite 来查询一些静态数据。当然,class 库使用 System.Data.Sqlite + System.Data.SQLite.Core + System.Data.SQLite.EF6 + System.Data.SQLite.Linq from NuGet。 WCF 项目本身不执行查询。它调用 class 库中的一个方法来完成它。
当我 运行 它在我的开发机器上时,一切都很好。但是在我将它部署到 Windows Server 2012 上的 IIS 后,抛出了异常 Unable to load DLL 'SQLite.Interop.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
。我确实进行了搜索,发现我需要在我的主要 WCF 项目中至少引用 System.Data.SQLite.Core,并确保它在每个文件夹中分别具有 x64 和 x86 文件夹以及相应的 Sqlite.Interop.dll。上述文件夹是使用 NuGet 引用自动生成的,位于 bin 文件夹下。所以我很高兴。已部署。同样的事情发生了:开发机器上一切正常,然后无法在服务器上加载 DLL。
我什至尝试在主 WCF 项目中引用所有 NuGet 包,但无济于事。然后我想到尝试手动将 dll 从 x64 文件夹复制到我的 bin 根文件夹,就在 wcf.dll 和 System.Data.SQLite.dll 旁边。现在错误消息更改为 Unable to load DLL 'SQLite.Interop.dll': Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
而不是未找到。
赋予它所有权限后,它成功了!
但这种行为让我觉得很奇怪,因为在我的开发机器和另一台测试服务器中我无法重现这种情况。只有在生产服务器上才会抛出此错误。
有什么我忽略的吗?顺便说一句,我试图将我的 WCF 项目从以 AnyCPU 为目标转变为仅以 x64 为目标。我尝试在 IIS AppPool 的高级设置中使用 Enable 32-bit。 None 一直工作到所有 DLL 都在 bin root 中。
我可能在这里有所作为。我做了一个procmon。看来x86下的dll找到成功了。但是,拒绝访问 CreateFile 操作。
现在看来是落入权限领域了。在测试环境和我的开发机器上,AppPool 拥有上帝的特权,所以问题无法重现。
TL;DR
然后我进入了许可细节。我发现 WCF apppool 身份仅对 x86\Sqlite.Interop.dll 具有 Read 权限。我添加了 Read and execute 并且问题消失了。您的 millage 可能会有所不同,它可能是需要许可的 x64。
经过思考:
现在我会花几天时间观察,但我认为就是这样。尽管从 procmon 说 Create File 失败,但这并不意味着它需要写权限。
进一步测试显示我的权限设置已关闭,因为我使用了 Visual Studio 部署功能来部署我的网站。在此过程中,它将我的网站根目录设置为 Read only.
我 运行 遇到了这个奇怪的问题。在我的 WCF 项目中,我引用了一个 class 库,它使用 SQLite 来查询一些静态数据。当然,class 库使用 System.Data.Sqlite + System.Data.SQLite.Core + System.Data.SQLite.EF6 + System.Data.SQLite.Linq from NuGet。 WCF 项目本身不执行查询。它调用 class 库中的一个方法来完成它。
当我 运行 它在我的开发机器上时,一切都很好。但是在我将它部署到 Windows Server 2012 上的 IIS 后,抛出了异常 Unable to load DLL 'SQLite.Interop.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
。我确实进行了搜索,发现我需要在我的主要 WCF 项目中至少引用 System.Data.SQLite.Core,并确保它在每个文件夹中分别具有 x64 和 x86 文件夹以及相应的 Sqlite.Interop.dll。上述文件夹是使用 NuGet 引用自动生成的,位于 bin 文件夹下。所以我很高兴。已部署。同样的事情发生了:开发机器上一切正常,然后无法在服务器上加载 DLL。
我什至尝试在主 WCF 项目中引用所有 NuGet 包,但无济于事。然后我想到尝试手动将 dll 从 x64 文件夹复制到我的 bin 根文件夹,就在 wcf.dll 和 System.Data.SQLite.dll 旁边。现在错误消息更改为 Unable to load DLL 'SQLite.Interop.dll': Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
而不是未找到。
赋予它所有权限后,它成功了!
但这种行为让我觉得很奇怪,因为在我的开发机器和另一台测试服务器中我无法重现这种情况。只有在生产服务器上才会抛出此错误。
有什么我忽略的吗?顺便说一句,我试图将我的 WCF 项目从以 AnyCPU 为目标转变为仅以 x64 为目标。我尝试在 IIS AppPool 的高级设置中使用 Enable 32-bit。 None 一直工作到所有 DLL 都在 bin root 中。
我可能在这里有所作为。我做了一个procmon。看来x86下的dll找到成功了。但是,拒绝访问 CreateFile 操作。
现在看来是落入权限领域了。在测试环境和我的开发机器上,AppPool 拥有上帝的特权,所以问题无法重现。
TL;DR 然后我进入了许可细节。我发现 WCF apppool 身份仅对 x86\Sqlite.Interop.dll 具有 Read 权限。我添加了 Read and execute 并且问题消失了。您的 millage 可能会有所不同,它可能是需要许可的 x64。
经过思考: 现在我会花几天时间观察,但我认为就是这样。尽管从 procmon 说 Create File 失败,但这并不意味着它需要写权限。
进一步测试显示我的权限设置已关闭,因为我使用了 Visual Studio 部署功能来部署我的网站。在此过程中,它将我的网站根目录设置为 Read only.