VS2013发布Web部署任务失败文件正在使用中

use*_*827 32 c# asp.net web-publishing visual-studio-2013

我使用VS2013 Premium将站点发布到Windows Server 2012.所有文件都发布正常,除了这些:SqlServerTypes\x64\msvcr100.dll

SqlServerTypes\64\SqlServerSpatial110.dll

SqlServerTypes\86\msvcr100.dll

SqlServerTypes\86\SqlServerSpatial110.dll

我为上面尝试发布的每个文件都遇到了这种错误:Web部署任务失败.(文件'msvcr100.dll'正在使用中.有关详细信息,请访问:http://go.microsoft.com/fwlink/?LinkId = 221672 #ERROR_FILE_IN_USE .)

有趣的是,这些文件是第一次发布(当它们不在服务器上时),然后它们不再被覆盖.试过2个不同的Web服务器.我在这里遵循了指南:http: //blogs.msdn.com/b/webdev/archive/2013/10/30/web-publishing-updates-for-app-offline-and-usechecksum.aspx

...但它只是设法使网站脱机(VS放置app_offline.htm)但发布仍然失败并出现相同的错误.所有其他文件发布完美.

有任何想法吗?

Say*_*imi 26

您可以在发布期间使应用程序脱机,希望释放文件锁定并允许您更新它.

不久前在博客上写了这篇文章.概述的支持是在Azure SDK和Visual Studio Update中提供的.我不记得确切的版本,但我可以找出是否需要.在博客文章附近/之后的任何更新都应该没问题.

先决条件:

  • VS 2012 + VS更新/ VS 2013 + VS更新/ VS2015
  • MSDeploy v3

注意:如果要从CI服务器发布,CI服务器也需要上面的更新

编辑发布配置文件

在VS中创建Web发布配置文件时,对话框中的设置存储在Properties\PublishProfiles\以.pubxml结尾的文件中.注意:还有一个.pubxml.user文件,不应该修改该文件

要在.pubxml文件中使您的应用离线,请添加以下属性.

<EnableMSDeployAppOffline>true</EnableMSDeployAppOffline>

笔记

ASP.NET必需

在MSDeploy端实现此方法的方法是将app_offline.htm文件放在网站/应用程序的根目录中.从那里,asp.net运行时将检测到并使您的应用程序脱机.因此,如果您的网站/应用程序没有启用asp.net,则此功能将无效.

它可能无法工作的情况

这样做的实现使得应用程序在发布开始之前可能不会严格脱机.首先删除app_offline.htm文件,然后MSDeploy将开始发布文件.它不等待ASP.NET检测文件并实际使其脱机.因此,您可能遇到仍然遇到文件锁的情况.默认情况下,VS启用重试,因此通常应用程序将在其中一个重试期间脱机,一切都很好.在某些情况下,ASP.NET可能需要更长时间才能响应.这有点棘手.

如果你添加<EnableMSDeployAppOffline>true</EnableMSDeployAppOffline>并且你的应用程序没有很快下线,那么我建议你在发布开始之前使应用程序脱机.有几种方法可以远程执行此操作,但这取决于您的设置.如果您只有MSDeploy访问权限,则可以尝试以下顺序:

  1. 用于msdeploy.exe删除app_offline.htm以使您的网站脱机
  2. 使用msdeploy.exe发布自己的应用(_make确保同步不会删除app_offline.htm _文件)
  3. 等待一段时间
  4. 发布网站
  5. 用于msdeploy.exe通过删除app_offline.htm使应用程序联机

我已经在http://sedodream.com/2012/01/08/howtotakeyourwebappofflineduringpublishing.aspx上写了你如何做到这一点.该博客文章中唯一缺少的是延迟等待网站实际脱机.您还可以创建一个msdeploy.exe直接调用的脚本,而不是将其集成到项目构建/发布过程中.

  • 实际上修复是你回答的想法和这里的大部分评论.基本上释放文件锁是必要的第一步.然后我决定删除包SQL Server Spacial Types(Spatial - by Microsoft)并删除罪魁祸首文件.然后我尝试使用SQL Server Spacial Types(#foo)NuGet包,因为我需要这些功能.不幸的是,虽然这个包没有发布的问题,但这些库的代码行为不正确.然后我删除了这个并返回到Microsoft软件包.现在发布工作正常,没有更多错误. (2认同)

Pau*_*aul 8

我在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的Spatial 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;
         }
    };
}
Run Code Online (Sandbox Code Playgroud)

这种方法有一个警告。假定您的应用程序是在使用Spatial dll的辅助进程中运行的唯一应用程序。由于应用程序池可以承载多个应用程序,因此如果另一个应用程序也已加载文件锁,则不会释放文件锁。这将防止您的部署处理相同的文件锁定错误。