3

我在 ASP.NET 应用程序中使用Microsoft.SqlServer.Types库。该库依赖于必须LoadLibrary()通过 P/Invoke 加载的本机 DLL。

该库的文档建议从Server.MapPath("~/bin"),但这会导致本机 DLL 被锁定,从而阻止应用程序的新部署。

因此,我正在考虑检索主网站 DLL 的卷影副本位置Assembly.GetExecutingAssembly().Location,将本机 DLL 复制到该位置,然后从那里加载它。

这样做安全吗?还是应该使用更安全的方法?

4

1 回答 1

2

我已经继续并实施了这个,它似乎工作正常。部署时没有锁定问题。

示例代码如下。您可能需要根据您的环境对其进行修改,它是为 OWIN 中托管的 Web API 2 编写的。

private void LoadSqlServerTypes()
{
    var shadowCopyDirectoryPath = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName;
    var nativeDllDirectory = new DirectoryInfo(HostingEnvironment.MapPath("~/bin/SqlServerTypes"));
    var nativeDllShadowCopyDirectory = Path.Combine(shadowCopyDirectoryPath, "SqlServerTypes");
    if (Directory.Exists(nativeDllShadowCopyDirectory) == false)
    {
        nativeDllDirectory.CopyTo(nativeDllShadowCopyDirectory, true);
    }

    SqlServerTypes.Utilities.LoadNativeAssemblies(shadowCopyDirectoryPath);
}

CopyTo方法是https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories上代码的修改版本

public static partial class DirectoryInfoExtensions
{
    /*
     * Source adapted from https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories
     */
     /// <summary>
     /// Copy a directory and its contents to a specified location.
     /// </summary>
     /// <param name="sourceDirectory">The directory to copy.</param>
     /// <param name="destinationDirectoryPath">The path of the new directory to create.</param>
     /// <param name="recursive">True if subdirectories must be copied; otherwise, false.</param>
    public static void CopyTo(this DirectoryInfo sourceDirectory, string destinationDirectoryPath, bool recursive)
    {
        if (Directory.Exists(destinationDirectoryPath) == false)
        {
            Directory.CreateDirectory(destinationDirectoryPath);
        }

        var files = sourceDirectory.GetFiles();
        foreach (var file in files)
        {
            string destinationFilePath = Path.Combine(destinationDirectoryPath, file.Name);
            file.CopyTo(destinationFilePath, false);
        }

        if (recursive == true)
        {
            var subdirectories = sourceDirectory.GetDirectories();
            foreach (DirectoryInfo directory in subdirectories)
            {
                string destinationSubdirectoryPath = Path.Combine(destinationDirectoryPath, directory.Name);
                CopyTo(new DirectoryInfo(directory.FullName), destinationSubdirectoryPath, recursive);
            }
        }
    }
}
于 2017-12-20T16:24:42.487 回答