DLLs and resource ID 2 manifests

Manifests at resource ID 2 help simplify the lives of DLL authors who want to consume side-by-side components via static imports. Just before processing your DLL's static imports and calling its entrypoint, the loader will create and activate an activation context based on the manifest that it finds at resource ID 2. This ensures that all your static imports are processed in the correct context - if this wasn't the case, binding your DLL's static imports would be affected by whoever was calling LoadLibrary("yourdll.dll"). Not a big deal, until you find out that they also had some dll loaded also called "zop.dll" with an export "Flarn", but whose parameter list looked completely different. The autoactivation ensures that your DLL is bound to the right "zop.dll" with the right "Flarn" export (at least subject to publisher policy.)

The logic (not the implementation) looks something like the following:

  1. LoadLibrary("yourdll.dll") is called by the application
  2. "yourdll.dll" is found using using the current context plus the usual DLL lookup mechanisms.
  3. When found, if yourdll.dll is not already loaded into this context, the DLL is mapped.
  4. CreateActCtx is called using the mapped DLL's HMODULE, passing resource ID MAKEINTRESOURCE(2) as the resource number.
  5. If that succeeded, the resulting context is activated.
  6. The static imports of "yourdll.dll" are resolved, possibly recursively executing these operations until all the statically referenced DLLs have been loaded.
  7. The DLL entrypoint for "yourdll.dll" is invoked.
  8. If a context was activated above, it's deactivated.
  9. Control returns to the application with an appropriate HMODULE

You can use any manifest you care to in your resource section. Visual Studio has options for embedding manifests at the right resource ID. Nikola has some tips for doing so in both makefiles and the VS IDE.

Publisher policy is of course applied, but application policy (ie: foo.exe.policy) is not. The usual "look in the app directory for private assemblies" logic applies as well, so this works even if your DLL is distributed privately with an application.  See also Using Side-By-Side Assemblies as a Resource, which covers when various resource values will be used during the loading and initialization of DLLs and executables.