我找到了
http://blogs.msdn.com/b/webdev/archive/2013/10/30/web-publishing-updates-for-app-offline-and-usechecksum.aspx上的解决方案
没有的原因为原始海报工作,我有一个解决方法。
EnableMSDeployAppOffline 方法的问题在于它只回收托管应用程序的应用程序域。它不会回收应用程序域所在的应用程序池工作进程 (w3wp.exe)。
拆除并重新创建应用程序域不会影响有问题的 Sql Server Spatial dll。这些 dll 是通过互操作 LoadLibray 调用手动加载的非托管代码。因此,dll 位于应用程序域的权限之外。
为了释放应用程序池进程对其施加的文件锁,您需要回收应用程序池,或手动从内存中卸载 dll。
Microsoft.SqlServer.Types nuget 包附带一个类,用于加载名为 SqlServerTypes.Utilities 的空间 dll。您可以修改 LoadNativeAssemblies 方法以在卸载应用程序域时卸载非托管 dll。通过此修改,当 msdeploy 复制 app_offline.htm 时,应用程序域将卸载然后卸载托管 dll。
[DllImport("kernel32.dll", SetLastError = true)]
internal extern static bool FreeLibrary(IntPtr hModule);
private static IntPtr _msvcrPtr = IntPtr.Zero;
private static IntPtr _spatialPtr = IntPtr.Zero;
public static void LoadNativeAssemblies(string rootApplicationPath)
{
if (_msvcrPtr != IntPtr.Zero || _spatialPtr != IntPtr.Zero)
throw new Exception("LoadNativeAssemblies already called.");
var nativeBinaryPath = IntPtr.Size > 4
? Path.Combine(rootApplicationPath, @"SqlServerTypes\x64\")
: Path.Combine(rootApplicationPath, @"SqlServerTypes\x86\");
_msvcrPtr = LoadNativeAssembly(nativeBinaryPath, "msvcr100.dll");
_spatialPtr = LoadNativeAssembly(nativeBinaryPath, "SqlServerSpatial110.dll");
AppDomain.CurrentDomain.DomainUnload += (sender, e) =>
{
if (_msvcrPtr != IntPtr.Zero)
{
FreeLibrary(_msvcrPtr);
_msvcrPtr = IntPtr.Zero;
}
if (_spatialPtr != IntPtr.Zero)
{
FreeLibrary(_spatialPtr);
_spatialPtr = IntPtr.Zero;
}
};
}
这种方法有一个警告。它假定您的应用程序是在工作进程中运行的唯一一个使用 Spatial dll 的应用程序。由于应用程序池可以托管多个应用程序,因此如果另一个应用程序也加载了文件锁,则不会释放它们。这将防止您的部署使用相同的文件锁定错误。