Domanda

We are using a wrapper DLL in order allow auto-updating of our application (our product is a DLL).

Where should we release the inner DLL when the application is closing?.

(We tried to do it in a DLLMain callback but it doesn't seem to work and the specs says that it shouldn't be there.)

Thank you

È stato utile?

Soluzione

This is very vague, it isn't clear at all what your wrapper does. In general, getting a DLL loaded into a process puts a lock on the file. This lock is created as a side-effect of Windows mapping the DLL into the process' virtual memory address space, the underlying system object is a memory-mapped file. Which will make any attempt to overwrite the file while updating it fail.

You should not have to do anything special in the "when the application is closing" case, that will get your DLL unloaded as well and releases the lock on the file.

The more typical problem is that you have no control at all over the process that loads the DLL. Your update cannot complete until that process has terminated. And clearly a DLL should never be in the business of forcibly terminating the host process, it cannot possibly judge what kind of damage that's going to do. A possible wrapper approach is one that has an entrypoint for every exported function that delegates the call to the real DLL. Whose entrypoints were found with GetProcAddress(), you can now use FreeLibrary() to get the real DLL unloaded so you can update it. That's very painful and error-prone when the DLL isn't trivial, you need a function pointer declaration for every exported function and use strings instead of function names. Maintenance is pretty brutal.

One possible alternative approach is the detail that the lock on the DLL is on the file data of the DLL, not on the directory entry. Which allows you to rename the file while it is loaded. Your update can now write the updated version with the same name. The next time the program starts, it will use your update. This is however not completely reliable, clearly the program will fail to start just as you are applying the update. Consider using a hard-link to avoid that failure mode.

Altri suggerimenti

I assume that you are dynamically loading the inner DLL from your wrapper DLL with LoadLibrary() after you've checked for (and potentially applied) an available update for the inner DLL.

If you have the cooperation of the host process using your wrapper DLL, you can export an Uninitialize() method that should be called by the host before exiting. In this routine you can call FreeLibrary() and do any other cleanup.

If you don't have the cooperation of the host process, then you are generally out of luck for cleaning up properly. As you've found, it is not permissible to call FreeLibrary() from within DllMain, and that is the only notification a DLL normally gets that a process is shutting down.

Leaking a DLL module handle during process shutdown is in practice not a big problem; the system is tracking all of the resources and will clean them up automatically.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top