c# - 无法从 x64/x86 加载 DLL 'SQLite.Interop.dll' 但能够与 System.Data.SQLite.dll 一起加载
问题描述
我遇到了这个奇怪的问题。在我的 WCF 项目中,我引用了一个使用 SQLite 查询一些静态数据的类库。自然,该类库使用来自 NuGet 的 System.Data.Sqlite + System.Data.SQLite.Core + System.Data.SQLite.EF6 + System.Data.SQLite.Linq。WCF 项目本身不执行查询。它从执行它的类库中调用一个方法。
当我在我的开发机器上运行它时,一切都很好。但是在我将它部署到 Windows Server 2012 上的 IIS 之后,Unable to load DLL 'SQLite.Interop.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
抛出了异常。我确实搜索了 SO,发现我需要在我的主 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))
而不是未找到。授予它所有权限后,它起作用了!
但是这种行为让我觉得很奇怪,因为在我的开发机器和另一台测试服务器上我无法重现它。只有在 prod 服务器上才会抛出此错误。
有什么我忽略的吗?顺便说一句,我试图将我的 WCF 项目从仅针对 AnyCPU 转向 x64。我尝试在 IIS AppPool 的高级设置中使用启用 32 位。在所有 DLL 都在 bin 根目录中之前,都没有工作。
解决方案
我可能会在这里做点什么。我做了一个procmon。在我看来,成功找到了x86下的dll。但是,它拒绝访问CreateFile操作。
现在看起来它落入了权限领域。在测试环境和我的开发机器上,AppPool 具有上帝的特权,因此无法重现问题。
TL;DR 然后我进入了权限细节。我发现 WCF apppool 身份仅对x86\Sqlite.Interop.dll具有读取权限。我添加了读取并执行,问题就消失了。你的 Millage 可能会有所不同,它可能是需要许可的 x64 版本。
之后的想法:现在我要花几天时间观察,但我认为就是这样。虽然从 procmon 它说创建文件失败,但这并不意味着它需要写权限。
进一步的测试表明我的权限设置已关闭,因为我使用 Visual Studio 部署功能来部署我的网站。在此过程中,它将我的网站根目录设置为只读。
推荐阅读
- jmeter - 带有formurlencoded数据请求的apache jmeter帖子失败
- r - 检查数据框中的任何列在 R 中是否相同
- sqlite - GROUP BY 后的总和
- java - C# 中的参数化 System.Type 变量
- matlab - 修改后的 Richardson 迭代 - 如何实现
- html - Reactjs,更改componentDidMount中的favicon
- c++ - UWP 应用服务中的多个部分结果
- node.js - 带有异步转换的长对象流过早结束
- python - 在 random.choices() 中使用索引 [0]
- c# - 我正在尝试匹配两个 xml 文件并从第一个文件中获取 xml 节点作为输出 xml