Wie bekomme ich IIS7, um eine gesperrte Datei freizugeben?

25

Während unserer Produktionserstellung wird eine sehr große (10 Megabyte) statische Inhaltsdatei im Stammverzeichnis manchmal von IIS gesperrt und kann von der Bereinigungsaufgabe nicht gelöscht werden. Dies liegt vermutlich daran, dass es zu diesem Zeitpunkt einem oder mehreren Kunden aktiv zur Verfügung gestellt wird.

Der Build-Prozess stoppt die Website vor der Bereinigung über

c:\Windows\System32\inetsrv\appcmd.exe stop site http://oursite.com

Dies gibt die Datei jedoch nicht frei - wir müssen IIS neu starten, damit der Prozess seine Sperre aufhebt.

appcmd.exeErmöglicht das vollständige Herunterfahren von IIS. das wollen wir nicht !

Gibt es andere Möglichkeiten, IIS dazu zu bringen, eine gesperrte Datei loszulassen, ohne IIS neu zu starten? Ein einfaches Stoppen und Starten der einzelnen Website kann die Dateisperre definitiv nicht aufheben.

Jarrod Dixon
quelle
1
Ernste Frage: Ändert sich diese statische Datei von Build zu Build oder handelt es sich nur um eine Datei, die sich nie ändern wird?
Splattne
Nur ein verrückter Gedanke, aber ich frage mich, was passieren würde, wenn Sie Schattenkopien für diesen Ordner aktivieren würden.
Richard West
Das ist deine sitemap.xml oder?
Dave Cheney
Ja, es war unsere sitemap.xml, aber jetzt haben wir nur eine MVC-Route dazu und speichern den Sucker im Speicher. Nie mehr abschließen!
Jarrod Dixon

Antworten:

12

Es gibt Tools wie den Sysinternal Process Explorer, die Dateihandles finden und zwangsweise schließen können. Der Status und das Verhalten der Anwendung (sowohl Ihre als auch in diesem Fall IIS) ist jedoch nicht definiert. Einige werden sich nicht darum kümmern, einige werden Fehler machen und andere werden schwer abstürzen.

Die richtige Lösung besteht darin, den Ausfall zu beheben und IIS zu ermöglichen, Sperren sauber freizugeben und nach sich selbst aufzuräumen, um die Serverstabilität zu gewährleisten. Wenn dies nicht möglich ist, können Sie entweder eine andere Site in derselben Box erstellen oder eine neue Box mit dem neuen Inhalt einrichten und den Domänennamen / die IP-Adresse verschieben, um den neuen Inhalt für die Produktion zu "bewerben".

Greg Arbeit
quelle
2
+1 für Prozess-Explorer, es kann Ihnen einen Einblick in die Fähigkeit geben, das Problem zu lösen, wenn Sie sehen, welcher Thread das Datei-Handle offen hält
Nick Kavadias
Vielleicht sehr nützlich freigegebene gesperrte Datei programmgesteuert mit Sysinternals-Tools mit Powershell , C # oder Skripten bat-cmd
Kiquenet
Ich habe IIS dazu gebracht, die Datei oder das Verzeichnis zu entsperren, indem ich einfach versuche, Dateien in diesen IIS-gesteuerten Ordner zu kopieren und dann die Webanwendung in einem Browser anzuzeigen. Manchmal gibt dieser Prozess diese Punkte frei.
Marc Noon
13

Ich benutze ein kleines Tool namens "Handle" , um dies zu tun.

Sie übergeben ihm im Grunde den Namen der gesperrten Datei und erfahren, welche Prozesse sie verwenden:

handle c:\weird.file
Something.exe pid: 1000 100: C:\weird.file
Something.exe pid: 1000 101: C:\weird.file

Dann geben Sie den Schalter -c ein, um den Griff zu schließen:

handle.exe -c 101 -p 1000 -y
handle.exe -c 100 -p 1000 -y

Möglicherweise haben Sie Schwierigkeiten, das in ein Build-Skript ohne ein Wrapper-Programm einzuarbeiten, um die Ausgabe zu analysieren, aber hoffentlich hilft dies.

Simon Johnson
quelle
Der mächtige Mark Russinovich zur Rettung - ich werde das überprüfen, aber Handles dringende Warnung vor Programminstabilität beim gewaltsamen Schließen eines Griffs macht mich nervös.
Jarrod Dixon
Hoffentlich ist jede Instabilität auf den betreffenden AppPool beschränkt. Wenn dies der Fall ist, können Sie den AppPool einfach neu starten, nachdem Sie die Sperre aufgehoben haben.
Simon Johnson
@ Jarrod: etwas Glück? Könnten Sie bitte Ergebnisse in Ihrem ursprünglichen Beitrag veröffentlichen? Ich würde gerne hinter den Kulissen sehen, was hier passiert.
Pure.Krome
Vielleicht sehr nützlich freigegebene gesperrte Datei programmgesteuert mit Handle with Powershell , C # oder Skripten bat-cmd und bekommen Prozesse, die einen Ordner sperren
Kiquenet
5

Ich bin nicht sicher, ob Sie die Kompilierung von Aspx-Dateien in temporären Assemblys meinen. Wir verwenden ASP.NET-Bereitstellungsprojekte , bei denen alle aspx / ascx-Dateien vorkompiliert werden.

Beim Kopieren der Binärdateien aus dem Ordner "publish" in den Ordner "bin" wird vorübergehend eine Datei "app_offline.htm" aktiviert, die nach dem Kopieren aller Assemblys entfernt wird (nur einige Sekunden). Auf diese Weise habe ich noch nie Dateisperren erlebt.

BEARBEITEN:

Sie könnten versuchen, den App-Pool mit appcmd.exe zu recyceln, anstatt die Website zu stoppen:

C:\Windows\System32\inetsrv\appcmd.exe recycle apppool "My App Pool Name"
splattne
quelle
1
Nein, es ist nur eine statische Inhaltsdatei im Stammverzeichnis - die Frage wird mit diesen Informationen aktualisiert!
Jarrod Dixon
1
Ich vermute, Sie verwenden die app_offline.htm während der Ausführung Ihres Build-Jobs?
Splattne
Ich denke, wir haben versucht, manuell ohne Erfolg zu recyceln, aber wir werden es beim nächsten Mal erneut versuchen, wenn es eine Sperre gibt (App-Pools sind für .NET, oder? Hier hilft das wahrscheinlich nicht weiter). Früher haben wir die Datei app_offline.htm erstellt, aber das hat beim Sperren nicht geholfen. Aus diesem Grund haben wir die einzelne Site entfernt.
Jarrod Dixon
Ich fürchte, du hast recht. Ich werde dies auf einem unserer Server testen und auf Sie zurückkommen.
Splattne
1
@splattne: Beim Recycling des Anwendungspools sollte das Handle entfernt worden sein, sofern die Datei von der Website geöffnet wurde. Wenn das Recycling des Pools nicht hilft, kann ich davon ausgehen, dass die Datei durch etwas anderes gesperrt wird.
pbz
1

Nicht die Antwort, sondern eine Problemumgehung für den Fall, dass diese Datei nicht "entsperrt" werden kann, ohne den IIS-Server neu zu starten:

Was passiert, wenn Sie einen neuen leeren Ordner erstellen / bereitstellen und das Ausgangsverzeichnis der Website in diesen Ordner ändern? Sie müssen jedoch einen neuen Ordnernamen erstellen oder zwischen zwei Namen wechseln.

Ich weiß nicht, in welchen Ordner diese Datei gehört. Wenn es sich nicht im Stammordner befinden muss, können Sie es in einem neu erstellten Ordner ablegen und ein virtuelles Verzeichnis erstellen, das auf diesen Ordner verweist. So können Sie Ihr Standard-Ausgangsverzeichnis für die Anwendung beibehalten.

splattne
quelle
1

Ich hatte das gleiche problem Jetzt bin ich zu MSDeploy (Web Deploy) gewechselt und kann die Website jetzt zuverlässig aktualisieren, ohne etwas zu stoppen. Tatsächlich ist dieser Schritt in unserem automatisierten Build-Tool skriptiert und läuft die ganze Zeit ohne Probleme ab. Und es ist auch schnell.

realMarkusSchmidt
quelle
0

Stoppen Sie den IIS-Dienst. Vielleicht verstehe ich etwas nicht, sorry.

Mark Allen
quelle
2
Wenn Sie den IIS - Dienst sind zu stoppen, werden Sie alle Web - Seiten nach unten ...
splattne
Dies ist eine Sache, die wir unbedingt vermeiden möchten, da wir nicht möchten, dass unsere CruiseControl.NET-Site heruntergefahren wird. Wir klicken während eines Builds auf die Schaltfläche "Status aktualisieren", um den Erfolg zu überprüfen.
Jarrod Dixon
Ok, wie wäre es, zuerst woanders zu bauen und dann über die statische Datei zu implementieren, anstatt alles auf diesem Server zu erledigen?
Mark Allen
Ist das nicht das Problem hier? Niemand sagte, dass die Datei von der Software auf dem Server selbst geändert wurde.
FlavorScape
0

Hinweis: Kein Experte für Windows-Dateisperrsemantik

Jarrod, kannst du die Datei aus dem Weg räumen? Möglicherweise können Sie Ihre neue Datei auch mit einer temporären Erweiterung erstellen und sie dann über die aktuelle Datei umbenennen.

Wenn die Windows-Dateisperrsemantik ähnlich wie bei POSIX funktioniert, sollten die Leser, die eine aktuelle Lesesperre für die Datei haben, die alte Datei weiterhin bedienen, bis sie ihre Lesestreams schließen, während neue Leser die neue Datei öffnen.

Dave Cheney
quelle
Nein, wir können die Datei erst nach einem Neustart von IIS bearbeiten.
Jarrod Dixon