Windows Can but Won’t
Windows actually can replace a DLL that is in use by renaming the original then copying the new file into place. However, the Windows world prefers not to do this. Why?
Even if you replace a file that is in use, there may still be code in the system that wants to use the old version. For example, suppose you have two files, A.DLL and B.DLL, which work together. You issue a patch that updates both of the files, but A.DLL is in use. No problem. You simply replace both of them. As a result, programs that were still using A.DLL keep using the old version, but new programs will use the new one. And all programs get the new version of B.DLL.
Now a program that was using the old A.DLL decides to call a function in. It naturally expects the old version of B.DLL, but instead it gets the new version. Depending on what sort of change you made to B.DLL, this call may work—or it may crash. Both DLLs assume that its partner comes from the same matched set.
Even if you're updating just a single DLL with no dependencies, there are still potential problems since the DLL has to interoperate with previous versions of itself.
Suppose you replace ole32.dll while it is in use. Then a newly launched program calls into the new ole32.dll and initiates a drag-drop operation. The user drags the object over a window created by one of the programs that launched before the update. You now have the new ole32.dll sending messages to the old ole32.dll.
When you write code that communicates between processes, you generally expect that the same version of the code will be running in each process, because the two endpoints in the communication channel have to agree on how they're going to communicate! "I'm going to send you message 5, which means 'request text,' and I expect you to reply by sending me message 12, which means 'here is the text you requested.'" If the two sides are not running the same version of the code, there's a chance that the communications mechanism will be different; it may be subtle, but it can, in fact, cause an incompatibility.
Say you added a field to a structure, and that structure happens to be used as part of message 5. Well, great. You now have two incompatible versions of message 5 out there—one that uses the old structure and one that uses the new structure. If the two sides of the communication disagree on the structure, message 5 will not work.
If you're going to support running the old and new versions side-by-side, then you have to invent a new message, say, message 52, and have the new version of the DLL support both message 5 and message 52. It has to figure out what version of the DLL is running on the other side first and send it the appropriate message.
Even if you haven't changed the structure itself, you may have changed the meaning of some fields in the structure. If the structure has an enumeration and the new version adds a new value to that enumeration, that's still an incompatibility between the old and new.
Sure, you can try to define new messages each time you issue a patch and write code to support interoperating between the old and new versions during the window in which two conflicting versions of the DLL are running at the same time. This, however, can get unwieldy when you're on your third patch and you have four different sets of messages—one for the original version and one for each of the patches.
Even if you require that the patches must be installed in sequence, it won't save you any effort; as long as you permit the original program to keep running, you have to continue interoperating with it.
And then people write articles complaining that you're an idiot because you're too slow to issue patches!
So it's not that Windows has to restart after replacing a file that is in use. It's just that it would rather not deal with the complexity that results if it doesn't. Engineering is a set of trade-offs. Do you go to the effort of supporting older versions of yourself for a situation that isn't even a recommended steady-state configuration?
Raymond Chen's Web site, The Old New Thing, and his identically titled book deal with Windows history and Win32 programming. He wishes you a safe trip home.