1

我正在尝试在 IIS 中使用 EFCore 3.1.16 解决 ASP.Net Framework 4.8 站点的问题。Microsoft.Data.SqlClient 在 SNI.dll 上有一个进程锁定,这会导致 IIS 中的 xcopy 部署出现问题。

我尝试了将 SNI.dll 复制到与 Microsoft.Data.SqlClient 相同的卷影副本位置的策略,因此它不必尝试访问 bin 文件夹中的 DLL,如https://github.com/中所述lscorcia/sqlclient.snishadowcopy

// Look for the main Microsoft.Data.SqlClient assembly in the 
// shadow copy path
var sqlClientShadowAssembly = Directory.GetFiles(
currentShadowPath, "Microsoft.Data.SqlClient.dll",
SearchOption.AllDirectories).FirstOrDefault();

// Extract the directory information from the shadow assembly path
var sqlClientShadowPath = 
Path.GetDirectoryName(sqlClientShadowAssembly);

// Find out the process bitness and choose the appropriate native 
// assembly
var moduleName = Environment.Is64BitProcess ? "x86\\SNI.dll"
        : "x64\\SNI.dll";
// Compute the source and target paths for the native assembly
var sourceFile = Path.Combine(currentPrivatePath, moduleName);
var targetFile = Path.Combine(sqlClientShadowPath, "SNI.dll");
File.Copy(sourceFile, targetFile);

但是,它仍然会首先尝试访问 bin 位置,而不是位于同一文件夹位置的 sni.dll。

我已经通过删除 DLL 并确认抛出 FileNotFound 异常来检查影子位置中的 Microsoft.Data.SqlClient 是否被正确使用。我还尝试直接复制到同一个文件夹中,并复制到其中的 x64 子文件夹中阴影位置。

4

1 回答 1

0

就我而言,仅当我的 IIS 应用程序位于 UNC 路径(例如“\\myserver\myshare\myapplication”)上时才会发生错误。这是在我的场景中有效的解决方法。

使用 P/Invoke 来SetDllDirectory

[DllImport(@"kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SetDllDirectory(string lpPathName);

(另请参阅有关 DLL 加载顺序的 MSDN 文章

然后,在我的 Global.asax.cs 方法的早期Application_Start(在任何数据库调用之前),这样调用它:

SetDllDirectory(Server.MapPath(@"~/bin"))

之后,一切都按预期工作。


我仍然认为这是一种黑客/解决方法,但至少,它现在在我的场景中工作。

据我了解,您可以SetDllDirectory多次调用以添加其他目录(即不覆盖现有目录)。

因此,如果有人阅读本文可能有其他程序集引用“x86”或“x64”文件夹中的本机 DLL,则可能会执行以下操作:

var bitness = Environment.Is64BitProcess ? @"x64" : @"x86";
SetDllDirectory(Server.MapPath($@"~/bin/{bitness}"));

我还尝试从本地路径(如“C:\Inetpub\wwwroot”)提供我的测试应用程序,在这里,即使没有调用SetDllDirectory.

我仍然不确定为什么错误只发生在 UNC 路径,而不是本地路径,因为我希望影子复制的托管程序集也会使DllImports 失败。


(我也在这个 GitHub 问题中发布了上述内容)

于 2022-01-22T05:22:21.523 回答