Ersetzen von DLL-Dateien, während die Anwendung ausgeführt wird?

18

Ich habe mehrere Spieleserver, die eine bestimmte DLL-Datei zum Ausführen verwenden. Manchmal muss ich die Spielserver aktualisieren, aber ich möchte die bereits laufenden Spiele nicht unterbrechen.

Gibt es eine Möglichkeit, die DLL-Datei zu ersetzen (sie ist von Windows gesperrt), sodass die nächsten Instanzen der Spieleserver, die diese Datei verwenden, die neue Version öffnen und die alten weiterhin die alte Version dieser DLL verwenden, bis sie neu gestartet werden ?

Ist es sicher, die Datei einfach mit einem dieser Tools zu entsperren und zu ersetzen?


quelle
Vielleicht nicht dein Spiel. Chrome wird jedoch aktualisiert, ohne Ihren Prozess zu unterbrechen. Leider ist dies anwendungsspezifisch. (Gehen Sie zu %LocalAppData%\Google\Chrome\Applicationund Sie sollten Ordner sehen, in 26.0.1410.64denen DLLs verschiedener Versionen gespeichert sind )
Alvin Wong
Abhängig von der jeweiligen Software können möglicherweise zwei oder mehr Instanzen (an verschiedenen Standorten) installiert und ausgeführt werden. Ineffizient, aber vielleicht machbar.
Harry Johnston

Antworten:

23

Eigentlich können Sie und es funktioniert in der Regel ohne Probleme (obwohl nicht immer)

Sie benennen die Datei um, ohne sie zu verschieben, und verschieben die neue Datei darüber. Auf diese Weise bleiben die Handles für die Datei gültig und funktionieren, sodass bereits vorhandene Instanzen weiterhin ordnungsgemäß auf die Datei zugreifen können und neue Instanzen (oder neue Handles) auf die neue Datei zugreifen.

Wenn ein Programm dieselbe DLL-Datei erneut öffnet und erwartet, dass sie exakt gleich bleibt, wird dies offensichtlich dadurch verhindert, dass beim Laden der DLL-Datei aus dem ausgeführten Code Verweise auf diese Ressourcen extrahiert werden ), dies wird zu Problemen führen, aber dies ist definitiv nicht die Norm.

Stephane
quelle
11

Nein . Auch wenn eine DLL kann vollständig in den physischen Speicher abgebildet werden , während die Anwendung ausgeführt wird , gibt es definitiv keine Garantie dafür ist. Teile von DLLs (und sogar ausführbare Dateien) können dem RAM zugeordnet werden, während andere Teile davon auf der Festplatte verbleiben, und können zu einem späteren Zeitpunkt eingelesen werden.

Das Ändern der Datei auf der Festplatte, während Windows Teile davon im RAM zugeordnet hat, würde nicht gut enden. Windows sperrt es aus gutem Grund.

Bearbeiten: Ich muss etwas klarstellen, da einige Leute die Absicht zu haben scheinen, Windows für das zu beschuldigen, was eigentlich ein Problem beim Anwendungsdesign ist , kein Problem beim Betriebssystemdesign.

Sie können DLLs aktualisieren, die von Anwendungen in Windows verwendet werden, ohne den Prozess zu beenden. Die Anwendung muss jedoch so geschrieben sein, dass signalisiert werden kann, dass die Assembly entladen werden soll. Warten Sie, bis die Aktualisierung abgeschlossen ist, und laden Sie dann die DLL erneut. Dies hat nichts mit dem Betriebssystem zu tun, das Sie ausführen. Es ist ein Problem beim Anwendungsdesign.

Bearbeiten: Sehen Sie sich auch Stephanes Antwort für eine mögliche Lösung an, die abhängig davon, wie Ihre spezifische Anwendung auf die Änderung der DLL reagiert, funktioniert. Ich denke, er verdient eine Gegenstimme.

Ryan Ries
quelle
Gibt es eine Möglichkeit, diese Datei an einen temporären Speicherort zu verschieben, damit sie später gelöscht werden kann, während eine neue an ihrem alten Speicherort abgelegt wird (also verwenden Server, die danach starten, die neue DLL)? Oder ist das Dateihandle mit dem Dateispeicherort verknüpft?
Das hängt ganz davon ab, wie die Anwendung geschrieben ist bzw. wie sie DLLs verwendet. Schauen Sie sich die Antwort von Greg Askew an. Wenn das Dateihandle geöffnet ist, können Sie nicht viel dagegen tun. Sie können die Dateizugriffsnummer mit Gewalt schließen, aber Sie werden mit ziemlicher Sicherheit zumindest Ihre App zum Absturz bringen, wenn nicht das gesamte Betriebssystem.
Ryan Ries
Also, was ist das für ein "guter Grund"? Bisher enthält Ihre Antwort keinen zwingenden Grund, warum Microsoft keine Hot-Swap-Funktion anbietet.
Konrad Rudolph
2

Nein, Sie sollten nicht an den vorhandenen Dateihandles basteln.

Wenn Sie das Laden der Assembly steuern und festlegen können, dass sie mit FileShare.Delete geöffnet wird, sollte es möglich sein, sie umzubenennen. Bestehende Prozesse verweisen weiterhin auf die umbenannte Assembly.

/programming/7147577/programmatically-rename-open-file-on-windows .

Greg Askew
quelle
2
Meiner Erfahrung nach können Sie in den meisten Fällen (jedenfalls mehr als die Hälfte der Zeit) eine DLL umbenennen (aber nicht löschen), ohne an der Anwendung herumzubasteln.
Harry Johnston
@ HarryJohnston: Ja, ich kann die DLL anscheinend umbenennen, auch wenn sie verwendet wird. Das werde ich wohl von jetzt an tun.
1

Nein, leider ist das nicht möglich.

Tut mir leid, um genau zu sein, es sei denn, es gibt eine späte Bindung, was bedeutet, dass die App diese DLL verwendet, wenn ein Teil des Codes in dieser DLL ausgeführt wird, aber sie ist immer noch nicht zuverlässig.

Danila Ladner
quelle
1

Sie können sich ansehen, wie der von asp.net gehostete Prozess funktioniert, und etwas Ähnliches entwickeln.

Es nimmt die gesamte Webanwendung und verschiebt sie an einen temporären Speicherort, von dem aus die Anwendung tatsächlich geladen wird. Anschließend wird ein Prozess zum Überwachen von Änderungen im ursprünglichen Ordner verlassen. Wenn diese erkannt werden, wird eine neue Instanz der Anwendung an einem neuen temporären Speicherort gestartet und neue Anforderungen werden an diese App umgeleitet. Die alte App wird dann heruntergefahren, sobald ausstehende Anforderungen abgeschlossen sind.

(Nitpicking, ja, es ist eine vereinfachte Ansicht der Dinge, in den meisten Fällen stellt IIS die Anforderungen in eine Warteschlange, bis die neue App die Aufgabe übernehmen kann.)

Thomas James
quelle
0

Vor ungefähr einem Jahrzehnt war ich ein glücklicher Benutzer von http://www.eggcentric.com/ISAPILoader.htm, das den IIS-ISAPI-DLL-Austausch live durchführte. Herr Egg unterstützt weiterhin seine FOSS-Lösung.

jkellydresser
quelle
0

NSIS Installer bietet eine Option: Beim Neustart auf Temp verschieben. Das Betriebssystem markiert einige Dateien, um sie beim nächsten Start an einen anderen Speicherort zu verschieben. Beim nächsten Start werden diese markierten Dateien automatisch an den zuvor ausgewählten neuen Speicherort verschoben. Eine kleine Suche darüber wird Sie diesbezüglich glücklich machen.

Shashank Kandhawe
quelle
Sie könnten in Ihrer Antwort eine vollständige Antwort angeben, anstatt dem OP die Aufforderung zu erteilen, nach einer Lösung zu suchen. Er würde nicht hier sein und fragen, ob er bereits eine Lösung gefunden hätte. Vielen Dank.
John aka hot2use