10

我在 ASP.NET(使用 .asmx)文件上构建了一个旧的 Web 服务。我需要使用 sodium.net - 不幸的是它在加载依赖的 libsodium.dll 文件时失败了。关于我做错了什么的任何想法?

  • 我通过 NuGet 添加了 libsodium.net。

  • 我已将 64 位 DLL 重命名为“libsodium.dll”(以及其他命名约定)。

  • 我试图直接引用 libsodium.dll 但 VS 拒绝它(不是有效的 DLL)。所以我将它添加为“内容”而不是“复制到输出”。

  • 构建完成后,我可以看到 website/Bin 文件夹包含 sodium.dll(.NET 程序集)和 libsodium.net。

  • 当我尝试使用 libsodium.net 时,我得到:

    错误 2015-02-02 11:14:27,118 13798ms [41] CabinetService doRequest - 捕获:“Sodium.SodiumCore”的类型初始化程序引发异常。System.TypeInitializationException:“Sodium.SodiumCore”的类型初始化程序引发了异常。---> System.DllNotFoundException:无法加载 DLL 'libsodium.dll':找不到指定的模块。(来自 HRESULT 的异常:0x8007007E)在 DynamicDllInvokeType.sodium_init() 在 Sodium.SodiumCore..cctor() --- 内部异常堆栈跟踪结束 --- 在 Sodium.SecretBox.Create(Byte) 的 Sodium.SodiumCore.LibraryName() [] message, Byte[] nonce, Byte[] key) at Macaroons.SecretBoxCryptoAlgorithm.Encrypt(Byte[] key, Byte[] plainText) in c:\Projects\Macaroons.Net\Macaroons.Net\SecretBoxCryptoAlgorithm.cs:line 58

因此,即使它位于 Bin 文件夹中,它也找不到“libsodium.dll”。我也确实尝试删除对“sodium.net”的依赖,在我收到运行时错误说“sodium.net”丢失后 - 当我重新添加它时,该错误消失了,我得到了上面的错误(表示“sodium.net”正确加载)。

所以我在“C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\cabinetservice”中打开网站影子文件夹并搜索“sodium”。唯一的结果是某些子文件夹中的“sodium.dll”。没有“libsodium.dll”。

因此,显然 ASP.NET 在创建网站的卷影副本时忽略了“libsodium.dll”文件。

我还尝试将 libsodium.dll(32 位)添加到 C:\Windows\System32 并将 libsodium.dll(64 位)添加到 C:\Windows\SysWOW64。结果相同。

我已经尝试过 C:\Windows\Microsoft.NET\assembly\GAC_32\libsodium 和 C:\Windows\Microsoft.NET\assembly\GAC_64\libsodium。结果相同。

如何让 ASP.NET 了解依赖关系?

4

2 回答 2

20

事实证明,ASP.NET 不会制作非托管 DLL(例如 libsodium.dll 和 libsodium-64.dll)的影子副本。

Sodium.dll(托管代码)尝试从与 Sodium.dll 的影子副本相同的目录(不起作用)加载 DLL,或者从 PATH 环境变量目录中的某个位置加载 DLL。

我的解决方案是在调用任何 Sodium 代码之前将 AppDomain \Bin 目录添加到路径中:

// Make it possible to load unmanaged libsodium DLLs that .NET does not make shadow copies of.
// -> Simply point the "path" variable to the Bin directory.
string path = Environment.GetEnvironmentVariable("PATH");
string binDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Bin");
Environment.SetEnvironmentVariable("PATH", path + ";" + binDir);

2018 年 1 月更新(来自 Jordan Rieger 的回答):

请注意,您可能还需要在服务器上安装 Microsoft Visual C++ 2015 Redistributable(x64 或 x86 目标,具体取决于您的进程。)

安装可再发行组件后,不要忘记重新启动您的应用程序池(我重置了 IIS)。

于 2015-07-31T09:50:45.223 回答
2

请注意,您可能还需要在服务器上安装 Microsoft Visual C++ 2015 Redistributable(x64 或 x86 目标,具体取决于您的进程。)

安装可再发行组件后,不要忘记重新启动您的应用程序池(我重置了 IIS)。

请参阅我对https://stackoverflow.com/a/45078280/284704的评论。

于 2018-01-24T23:16:19.967 回答