Close DLL file handle opened by LoadLibrary

Viewed 1158

How can I close the file handle opened by a LoadLibrary call on a .dll while keeping the library loaded? FreeLibrary will not work for example.

In my case there is a program I want to keep open that has the DLL open, but I don't want to close the program each time I recompile and replace the DLL. I don't care if the program has an old version of the library in memory. The DLL is also used by another program which is why I want to be able to replace it.

1 Answers

It's not possible because a "loaded" DLL is a memory mapped file. This means that "closing the handle" would remove it from memory because it's not copied to memory, only mapped.

This is why DLLs are so memory efficient as long as all programs use the exact same file - it (almost) doesn't cost any extra memory to load it hundreds of times! (In case you wonder: it's mapped as copy-on-write so modifying it in memory won't modify the file on disk but instead copy the one affected 4k page to actual memory and modify it there.)

You can however rename the file (or move it, as long as it's on the same volume, which is technically also a renaming operation) while it's still in use. Then you can create a new file with the original name and later delete the old file after it was unloaded everywhere.

You can also mark the old file as to be deleted automatically on the next reboot using MoveFileEx(MOVEFILE_DELAY_UNTIL_REBOOT) but this requires elevated privileges. A popular choice by non-elevated updaters/uninstallers to avoid that is to drop a batch or vbs file in the local appdata folder that deletes the file and then itself (which does work because scripts are copied to memory) and register it in the per-user RunOnce registry key.

(Note that opening the file with FILE_FLAG_DELETE_ON_CLOSE won't work.)

Related