I have very simple exe and dll just to test. Here is the code in exe process:
auto lib = ::LoadLibrary("CppDll.dll");
auto bar = (Bar)::GetProcAddress(lib, "Bar");
bar();
while (::FreeLibrary(lib));
When after this I'm trying to delete the dll file I see the following:
I also looked into Modules and I'm puzzled
auto lib = ::LoadLibrary("CppDll.dll");
auto bar = (Bar)::GetProcAddress(lib, "Bar");
bar();
while (::FreeLibrary(lib));
So after call to bar()
there are two of them. And after FreeLibrary
still, one left.
What can I do to delete the file?
UPD: I have just discovered that this happens only if the dll supports clr.
This seems to be impossible. An app that hosts CLR uses CLRCreateInstance
from which it can get ICLRMetaHost
interface on which it can call GetRuntime
in order to create CLR. But the interface doesn't have members to unload CLR. Its Stop
method stops code execution in CLR but does not release, resources or unload appdomains. But to unload an assembly we must unload all appdomains which use it.
So, to be able to unload an assembly one needs to load it into a separate appdomain and then unload the appdomain. But it is impossible to unload DLL that loads CLR, CLR can be unloaded only when the process is exiting.
Richter, CLR via C#. Chapter 22 "CLR Hosting and AppDomains":
The first AppDomain created when the CLR is initialized is called the default AppDomain; this AppDomain is destroyed only when the Windows process terminates.