webentwicklung-frage-antwort-db.com.de

VS2013 Publish Web Deployment-Task fehlgeschlagen Die Datei wird verwendet

Ich verwende VS2013 Premium, um eine Site auf Windows Server 2012 zu veröffentlichen. Alle Dateien werden mit Ausnahme der folgenden Dateien veröffentlicht: SqlServerTypes\x64\msvcr100.dll

SqlServerTypes\x64\SqlServerSpatial110.dll

SqlServerTypes\x86\msvcr100.dll

SqlServerTypes\x86\SqlServerSpatial110.dll

Ich bekomme diese Art von Fehlern für jede der oben genannten Dateien, die ich zu veröffentlichen versuchte: Die Webbereitstellungsaufgabe ist fehlgeschlagen. (Die Datei 'msvcr100.dll' wird verwendet. Weitere Informationen finden Sie unter: http://go.Microsoft.com/fwlink/?LinkId=221672#ERROR_FILE_IN_USE .)

Interessanterweise wurden diese Dateien das erste Mal veröffentlicht (wenn sie nicht auf dem Server waren), dann werden sie nicht mehr überschrieben. Ich habe es mit 2 verschiedenen Webservern versucht. Ich habe die Anleitung hier befolgt: http://blogs.msdn.com/b/webdev/archive/2013/10/30/web-publishing-updates- für-app-offline-and-usechecksum.aspx

... Es ist jedoch nur gelungen, die Site offline zu setzen (VS setzt die Datei app_offline.htm), aber das Publizieren schlägt immer noch mit dem gleichen Fehler fehl .. _. Alle anderen Dateien werden einwandfrei veröffentlicht.

Irgendwelche Ideen?

28
user3546827

Sie können Ihre App während der Veröffentlichung offline schalten, was hoffentlich die Sperre für die Datei freigeben und die Aktualisierung ermöglichen soll.

Ich darüber gebloggt vor einiger Zeit. Der beschriebene Support wurde im Azure SDK und Visual Studio Update bereitgestellt. Ich kann mich nicht an die genauen Releases erinnern, kann aber bei Bedarf herausfinden. Jedes Update aus/nach diesem Blog-Post sollte in Ordnung sein.

Voraussetzungen:

  • VS 2012 + VS Update/VS 2013 + VS Update/VS2015
  • MSDeploy v3

Hinweis: Wenn Sie von einem CI-Server aus veröffentlichen, benötigt der CI-Server auch die oben genannten Updates.

Bearbeiten Sie das Veröffentlichungsprofil

Beim Erstellen eines Web Publish-Profils in VS werden die Einstellungen aus dem Dialogfeld in Properties\PublishProfiles\ als Dateien gespeichert, die auf .pubxml enden. Hinweis: Es gibt auch eine .pubxml.user-Datei, diese Datei sollte nicht geändert werden.

Fügen Sie die folgende Eigenschaft hinzu, um Ihre App in der .pubxml-Datei offline zu schalten.

<EnableMSDeployAppOffline>true</EnableMSDeployAppOffline>

Anmerkungen

ASP.NET Erforderlich

Dies wurde auf der MSDeploy-Seite so implementiert, dass eine app_offline.htm -Datei im Stammverzeichnis der Website/app abgelegt wird. Von dort erkennt die asp.net-Laufzeit dies und bringt Ihre App offline. Wenn auf Ihrer Website/App asp.net nicht aktiviert ist, funktioniert diese Funktion nicht.

Fälle, in denen dies möglicherweise nicht funktioniert

Die Implementierung davon macht es so, dass die App vor dem Beginn der Veröffentlichung nicht unbedingt offline ist. Zuerst wird die Datei app_offline.htm gelöscht, dann beginnt MSDeploy mit der Veröffentlichung der Dateien. Es wartet nicht darauf, dass ASP.NET die Datei erkennt und tatsächlich offline stellt. Aus diesem Grund können Sie auf Fälle stoßen, in denen Sie immer noch die Dateisperre ausführen. Standardmäßig aktiviert VS Wiederholungen, sodass die App normalerweise während einer Wiederholung offline geschaltet wird und alles gut ist. In einigen Fällen kann es länger dauern, bis ASP.NET reagiert. Das ist etwas kniffliger.

Falls Sie <EnableMSDeployAppOffline>true</EnableMSDeployAppOffline> hinzufügen und Ihre App nicht schnell genug offline ist, schlage ich vor, dass Sie die App offline schalten, bevor die Veröffentlichung beginnt. Es gibt verschiedene Möglichkeiten, dies aus der Ferne zu tun, aber das hängt von Ihrem Setup ab. Wenn Sie nur über MSDeploy verfügen, können Sie die folgende Reihenfolge versuchen:

  1. Verwenden Sie msdeploy.exe, um Ihre Site offline zu setzen, indem Sie app_offline.htm löschen
  2. Verwenden Sie msdeploy.exe, um Ihre App zu veröffentlichen (_Stellen Sie sicher, dass die Synchronisierung die Datei app_offline.htm nicht löscht_)
  3. Warten Sie etwas Zeit
  4. Veröffentlichen Sie die Site
  5. Verwenden Sie msdeploy.exe, um die App online zu bringen, indem Sie app_offline.htm löschen

Ich habe gebloggt, wie Sie dies unter http://sedodream.com/2012/01/08/howtotakeyourwebappofflineduringpublishing.aspx erreichen können. Das einzige, was in diesem Blogpost fehlt, ist die Verzögerung, bis die Website tatsächlich offline gestellt wird. Sie können auch ein Skript erstellen, das einfach msdeploy.exe direkt aufruft, anstatt es in den Projekterstellungs-/Veröffentlichungsprozess zu integrieren.

23

Ich habe den Grund gefunden, warum die Lösung unter http://blogs.msdn.com/b/webdev/archive/2013/10/30/web-publishing-updates-for-app-offline-and- usechecksum.aspx hat für das ursprüngliche Poster nicht funktioniert, und ich habe eine Problemumgehung.

Das Problem des Ansatzes EnableMSDeployAppOffline besteht darin, dass nur die App-Domäne wiederverwendet wird, in der sich die Anwendung befindet. Der Arbeitsprozess des Anwendungspools (w3wp.exe), in dem sich die App-Domäne befindet, wird nicht wieder hergestellt. 

Das Entfernen und Wiederherstellen der App-Domäne wirkt sich nicht auf die betreffenden SQL-Server-Spatial-DLLs aus. Diese DLLs sind nicht verwalteter Code, der manuell über Interop LoadLibray-Aufrufe geladen wird. Daher befinden sich die DLLs außerhalb des Bereichs der App-Domäne.

Um die Dateisperren aufzuheben, die der App-Pool-Prozess für sie bereitstellt, müssen Sie den App-Pool entweder erneut verwenden oder die DLLs manuell aus dem Arbeitsspeicher entfernen.

Das Microsoft.SqlServer.Types-Nuget-Paket enthält eine Klasse, die zum Laden der Spatial-DLLs mit dem Namen SqlServerTypes.Utilities verwendet wird. Sie können die LoadNativeAssemblies-Methode ändern, um die nicht verwalteten DLLs zu entladen, wenn die App-Domäne entladen wird. Wenn msdeploy mit dieser Änderung die app_offline.htm kopiert, werden die verwalteten DLLs ebenfalls von der App-Domäne entladen und anschließend entladen.

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;
         }
    };
}

Bei diesem Ansatz gibt es eine Einschränkung. Es wird davon ausgegangen, dass Ihre Anwendung die einzige ist, die im Arbeitsprozess ausgeführt wird und die Spatial-DLLs verwendet. Da App-Pools mehrere Anwendungen hosten können, werden die Dateisperren nicht freigegeben, wenn sie auch von einer anderen Anwendung geladen wurden. Dadurch wird verhindert, dass Ihre Bereitstellung mit demselben Dateisperrfehler arbeitet.

4
Paul

Ich denke, was am einfachsten ist, ist, diese DLLs als CopyLocal als wahr zu machen. Ich gehe davon aus, dass diese DLLs aus dem Programmordner gezogen werden. Markieren Sie sie als kopylokal als "true" und führen Sie eine Bereitstellung durch. Versuchen Sie, einen IIS lokalen Prozess auf Ihrem lokalen Computer zu stoppen.

1
qamar

Es gibt bekannte Probleme mit IIS und Dateisperren (warum sie noch nicht gelöst wurden, weiß ich nicht).

Die Frage, die ich stellen möchte, ist jedoch, ob Sie diese Dateien überhaupt erneut bereitstellen müssen.

Ich erkenne die Dateinamen und erinnere mich daran, dass es sich um Systemdateien handelt, die entweder bereits auf dem Server vorhanden sein müssen oder einfach nicht erneut bereitgestellt werden müssen.

Ich bin nicht sehr erfahren, wenn es um IIS geht, aber ich bin schon früher auf dieses Problem gestoßen, und einige meiner erfahreneren Mitarbeiter haben mir gesagt, dass dies, wie gesagt, eine bekannte IIS-Ausgabe ist und ich die Antwort glaube zu deiner Frage lautet:

  1. Vermeiden Sie die Bereitstellung unnötiger Dateien.
  2. versuchen Sie es nochmal
  3. Website zurücksetzen
  4. versuchen Sie es nochmal
  5. iisreset
1
DOOMDUDEMX

Beachten Sie, dass Sie nicht über einen dieser neuen Cloud-Backup-Dienste verfügen, der Dateisperren annimmt. Außerdem haben Sie im Explorer oder einem DLL -Inspektionstool keine offenen Objekte.

Ich finde es irgendwie lächerlich, dass MS keine besseren Vorkehrungen für dieses Problem trifft. Ich finde, dass 9 von 10 von 10 meine Bereitstellung gut funktioniert, aber dann, wenn unser Traffic zunimmt, kann das 1 zu 10 werden.

Ich werde das Problem lösen mit:

  • zwei Anwendungen MySite.A und MySite.B, wobei jeweils nur eine ausgeführt wird. 
  • Ich werde dann immer auf der ruhenden Site installieren. 
  • Wenn während der Bereitstellung ein Problem auftritt, führt dies niemals zum Ausfall der gesamten Site.
  • Wenn nach der Bereitstellung ein schwerwiegendes Problem auftritt, können Sie sehr leicht zurückkehren.

Ich weiß nicht genau, wie ich es umsetze, aber ich denke, das ist, was ich tun muss.

0
Simon_Weaver