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

时间:2014-12-05 22:50:02

标签: c# asp.net visual-studio-2013 web-publishing

我正在使用VS2013 Premium将站点发布到Windows Server 2012。 所有文件发布正常,除了这些: SqlServerTypes \ 64 \ 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)但发布仍然失败并出现相同的错误。 所有其他文件发布完美。

有什么想法吗?

5 个答案:

答案 0 :(得分:25)

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

blogged about this一会儿回来。概述的支持是在Azure SDK和Visual Studio Update中提供的。我不记得确切的版本,但我可以找出是否需要。在该博客文章附近/之后的任何更新都应该没问题。

先决条件:

  • VS 2012 + VS update / VS 2013 + VS Update / 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. 通过删除app_offline.htm
  2. ,使用msdeploy.exe使您的网站脱机
  3. 使用msdeploy.exe发布您的应用(_确保同步不会删除app_offline.htm文件_)
  4. 等待一段时间
  5. 发布网站
  6. 使用msdeploy.exe删除app_offline.htm
  7. ,将应用程序联机

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

答案 1 :(得分:6)

我找到了解决方案的原因 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是非托管代码,通过interop LoadLibray调用手动加载。因此,dll不在app域的范围之内。

为了释放应用程序池进程对其进行的文件锁定,您需要回收应用程序池,或者手动从内存中卸载dll。

Microsoft.SqlServer.Types nuget包附带一个类,用于加载名为SqlServerTypes.Utilities的Spatial dll。您可以修改LoadNativeAssemblies方法以在卸载应用程序域时卸载非托管dll。通过此修改,当msdeploy复制app_offline.htm时,app域将卸载然后卸载托管dll。

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的工作进程中运行的唯一应用程序。由于应用程序池可以托管多个应用程序,因此如果另一个应用程序也加载了它们,则不会释放文件锁这将阻止您的部署使用相同的文件锁定错误。

答案 2 :(得分:1)

IIS和文件锁存在已知问题(为什么它们还没有解决但我不知道)。

我想问的问题是,你是否需要重新部署这些文件?

我识别文件名并将它们记为系统文件,这些文件应该已经存在于服务器上,或者根本不需要重新部署。

我对IIS不是很有经验,但我之前遇到过这个问题,我的一些经验丰富的同事告诉我,这就像我说的一个已知的IIS问题,我相信答案你的问题是:

  1. 避免部署不必要的文件。
  2. 再试一次
  3. 重置网站
  4. 再试一次
  5. IISRESET

答案 3 :(得分:1)

我认为最简单的方法是将这些dll设为CopyLocal为true。我假设这些dll是从程序文件文件夹中提取出来的。尝试将它们标记为copylocal true并进行部署。尝试停止在本地计算机上运行的任何IIS本地进程。

答案 4 :(得分:0)

请注意,您没有运行带有文件锁定的新型云备份服务之一 - 而且您还没有在资源管理器或DLL检查工具中打开任何内容。

我认为MS没有为这个问题做出更好的规定,这有点荒谬。我发现9次中有10次我的部署运行得很好,但随后我们的流量增加了10次就会变成1次。

我将用以下方法解决问题:

  • 两个应用MySite.AMySite.B,其中一次只有一个正在运行。
  • 然后我总是部署到休眠站点。
  • 如果在部署过程中出现问题,则永远不会导致整个网站停机。
  • 如果部署后出现严重问题,您可以轻松恢复。

我不太确定我是如何实现它的,但我认为这是我需要做的。