Windows ConfidentialWindows kann’s, tut’s aber nicht

Raymond Chen

Windows kann eine DLL, die gerade verwendet wird, ersetzen, indem das Original umbenannt und die neue Datei dann an diese Stelle kopiert wird. In der Windows-Welt wird jedoch bevorzugt, dies nicht zu tun. Warum?

Selbst wenn Sie eine Datei ersetzen, die gerade verwendet wird, könnte im System noch Code vorhanden sein, der die alte Version verwenden möchte. Angenommen, Sie haben zwei Dateien (A.DLL und B.DLL), die zusammenarbeiten. Sie veröffentlichen einen Patch, der beide Dateien aktualisiert, aber A.DLL wird gerade verwendet. Kein Problem. Sie ersetzen einfach beide. Demzufolge verwenden Programme, die noch die A.DLL-Datei verwendet haben, weiterhin die alte Version, während neue Programme die neue verwenden. Und alle Programme erhalten die neue Version von B.DLL.

Jetzt entscheidet ein Programm, das die alte A.DLL-Datei verwendet hat, eine Funktion aufzurufen. Es erwartet naturgemäß die alte Version von B.DLL, aber stattdessen wird die neue Version abgerufen. In Abhängigkeit von der Art der Änderung an der B.DLL-Datei kann dieser Aufruf funktionieren, oder es kommt zu einem Absturz. Beide DLLs nehmen an, dass ihr Partner aus demselben entsprechenden Satz stammt.

Selbst wenn Sie nur eine einzige DLL ohne Abhängigkeiten aktualisieren, gibt es immer noch mögliche Probleme, da die DLL mit früheren Versionen ihrer selbst zusammenarbeiten muss.

Angenommen, Sie ersetzen ole32.dll, während die Datei verwendet wird. Ein neu gestartetes Programm ruft die neue ole32.dll auf und initiiert einen Drag & Drop-Vorgang. Der Benutzer zieht das Objekt über ein Fenster, das von einem der vor der Aktualisierung gestarteten Programme erstellt wurde. Die neu ole32.dll sendet nun Nachrichten an die alte ole32.dll.

Wenn Sie Code schreiben, der mit Prozessen kommuniziert, erwarten Sie gewöhnlich, dass dieselbe Version des Codes in jedem Prozess ausgeführt wird, da sich die beiden Endpunkte im Kommunikationskanal darauf einigen müssen, wie diese Kommunikation erfolgt. „Ich sende Nachricht 5, d. h. 'Textanforderung', und ich erwarte eine Antwort in Form von Nachricht 12, d. h. 'hier ist der angeforderte Text'.“ Wenn bei den beiden Seiten nicht dieselbe Codeversion ausgeführt wird, besteht die Möglichkeit, dass die Kommunikationsmethode eine andere ist. Es könnte ein feiner Unterschied sein, aber tatsächlich eine Inkompatibilität verursachen.

Angenommen, Sie haben einer Struktur ein Feld hinzugefügt, und diese Struktur wird als Teil von Nachricht 5 verwendet. Sie haben dann zwei unvereinbare Versionen von Nachricht 5: eine, die die alte Struktur verwendet, und eine, die die neue Struktur benutzt. Wenn die beiden Seiten der Kommunikation im Hinblick auf die Struktur nicht übereinstimmen, funktioniert Nachricht 5 nicht.

Wenn Sie die Nebeneinanderausführung der alten und neuen Version unterstützen möchten, müssen Sie eine neue Nachricht erfinden, beispielsweise Nachricht 52, wobei die neue Version der DLL sowohl Nachricht 5 als auch Nachricht 52 unterstützt. Die Datei muss zuerst herausfinden, welche Version der DLL auf der anderen Seite ausgeführt wird, bevor sie die entsprechende Nachricht senden kann.

Selbst wenn Sie die Struktur an sich nicht geändert haben, könnten Sie die Bedeutung einiger Felder in der Struktur geändert haben. Wenn die Struktur eine Enumeration enthält und die neue Version dieser Enumeration einen neuen Wert hinzufügt, bedeutet dies immer noch eine Inkompatibilität zwischen der alten und neuen Version.

Natürlich können Sie versuchen, jedes Mal neue Nachrichten zu definieren, wenn Sie einen Patch veröffentlichen und Code schreiben, um die Zusammenarbeit der alten und der neuen Version zu unterstützen, während zwei widersprüchliche Versionen der DLL gleichzeitig ausgeführt werden. Dies kann jedoch aufwändig werden, wenn es sich um den dritten Patch handelt und Sie vier verschiedene Nachrichtensätze haben – jeweils eine Nachricht für die ursprüngliche Version und eine für jeden Patch.

Selbst wenn Sie fordern, dass die Patches nacheinander installiert werden müssen, führt dies nicht zu Einsparungen. Solange Sie zulassen, dass das ursprüngliche Programm weiter ausgeführt wird, müssen Sie weiterhin mit ihm zusammenarbeiten.

Und dann beschweren sich Leute darüber, dass Sie ein Idiot sind, weil Sie beim Veröffentlichen von Patches zu langsam sind!

Es ist nicht so, dass Windows unbedingt neu gestartet werden muss, nachdem eine Datei ersetzt wurde, die gerade verwendet wird. Es ist vielmehr so, dass es sich nicht mit den Problemen herumschlagen möchte, die sich ergeben, wenn es nicht neu gestartet wird. Bei der Entwicklung müssen immer Kompromisse eingegangen werden. Würden Sie ältere Versionen in einer Situation unterstützen, bei der es sich nicht einmal um eine empfohlene Konfiguration für einen stabilen Zustand handelt?

Raymond Chen befasst sich auf seiner Website „The Old New Thing“ und in seinem gleichnamigen Buch mit der Geschichte von Windows und mit der Win32-Programmierung. Er wünscht Ihnen eine gute Heimfahrt.