如何在 ASP.NET 上包含 libsodium.net
How to include libsodium.net on ASP.NET
我有一个基于 ASP.NET(使用 .asmx)文件的旧 Web 服务。我需要使用 sodium.net - 不幸的是它在加载相关的 libsodium.dll 文件时失败了。关于我做错了什么有什么想法吗?
我已经通过 NuGet 添加了库sodium.net。
我已将 64 位 DLL 重命名为 "libsodium.dll"(以及其他命名约定)。
我试图直接引用 libsodium.dll 但 VS 拒绝它(不是有效的 DLL)。所以我将其添加为 "content" 而不是 "copy to output".
构建后,我可以看到 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.SodiumCore.LibraryName()
在 Sodium.SecretBox.Create(字节 [] 消息,字节 [] 随机数,字节 [] 密钥)
在 Macaroons.SecretBoxCryptoAlgorithm.Encrypt(Byte[] key, Byte[] plainText) 在 c:\Projects\Macaroons.Net\Macaroons.Net\SecretBoxCryptoAlgorithm.cs:line 58
所以它找不到 "libsodium.dll" 即使它在 Bin 文件夹中。我也确实尝试删除对 "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 知道依赖关系?
事实证明 ASP.NET 不会制作非托管 DLL 的卷影副本,例如 libsodium.dll 和 libsodium-64.dll。
Sodium.dll(托管代码)尝试从与 Sodium.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 的回答):
Note that you may also need to install the Microsoft Visual C++ 2015
Redistributable on your server (either the x64 or x86 target,
depending on your process.)
Don't forget to restart your app pool (I did an IIS reset) after
installing the redistributable.
请注意,您可能还需要在服务器上安装 Microsoft Visual C++ 2015 Redistributable(x64 或 x86 目标,具体取决于您的进程。)
不要忘记在安装可再发行组件后重新启动您的应用程序池(我重置了 IIS)。
查看我对 的评论。
我有一个基于 ASP.NET(使用 .asmx)文件的旧 Web 服务。我需要使用 sodium.net - 不幸的是它在加载相关的 libsodium.dll 文件时失败了。关于我做错了什么有什么想法吗?
我已经通过 NuGet 添加了库sodium.net。
我已将 64 位 DLL 重命名为 "libsodium.dll"(以及其他命名约定)。
我试图直接引用 libsodium.dll 但 VS 拒绝它(不是有效的 DLL)。所以我将其添加为 "content" 而不是 "copy to output".
构建后,我可以看到 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.SodiumCore.LibraryName() 在 Sodium.SecretBox.Create(字节 [] 消息,字节 [] 随机数,字节 [] 密钥) 在 Macaroons.SecretBoxCryptoAlgorithm.Encrypt(Byte[] key, Byte[] plainText) 在 c:\Projects\Macaroons.Net\Macaroons.Net\SecretBoxCryptoAlgorithm.cs:line 58
所以它找不到 "libsodium.dll" 即使它在 Bin 文件夹中。我也确实尝试删除对 "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 知道依赖关系?
事实证明 ASP.NET 不会制作非托管 DLL 的卷影副本,例如 libsodium.dll 和 libsodium-64.dll。
Sodium.dll(托管代码)尝试从与 Sodium.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 的回答):
Note that you may also need to install the Microsoft Visual C++ 2015 Redistributable on your server (either the x64 or x86 target, depending on your process.)
Don't forget to restart your app pool (I did an IIS reset) after installing the redistributable.
请注意,您可能还需要在服务器上安装 Microsoft Visual C++ 2015 Redistributable(x64 或 x86 目标,具体取决于您的进程。)
不要忘记在安装可再发行组件后重新启动您的应用程序池(我重置了 IIS)。
查看我对