手动将本机 DLL 复制到卷影复制目录是否安全?
Is it safe to manually copy native DLLs to a Shadow Copy directory?
我在 ASP.NET 应用程序中使用 Microsoft.SqlServer.Types 库。该库依赖于必须通过 P/Invoke.
使用 LoadLibrary()
加载的本机 DLL
库的文档建议从 Server.MapPath("~/bin")
加载本机 DLL,但这会导致本机 DLL 被锁定,从而阻止应用程序的新部署。
因此我想用 Assembly.GetExecutingAssembly().Location
检索主网站 DLL 的卷影副本位置,将本机 DLL 复制到该位置,然后从那里加载它。
这样做安全吗?或者应该使用更安全的方法?
我已经开始实施这个,它似乎工作正常。部署时没有锁定问题。
示例代码如下。您可能需要根据您的环境修改它,它是为 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);
}
}
}
}
我在 ASP.NET 应用程序中使用 Microsoft.SqlServer.Types 库。该库依赖于必须通过 P/Invoke.
使用LoadLibrary()
加载的本机 DLL
库的文档建议从 Server.MapPath("~/bin")
加载本机 DLL,但这会导致本机 DLL 被锁定,从而阻止应用程序的新部署。
因此我想用 Assembly.GetExecutingAssembly().Location
检索主网站 DLL 的卷影副本位置,将本机 DLL 复制到该位置,然后从那里加载它。
这样做安全吗?或者应该使用更安全的方法?
我已经开始实施这个,它似乎工作正常。部署时没有锁定问题。
示例代码如下。您可能需要根据您的环境修改它,它是为 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);
}
}
}
}