0
votes

OK, so I have successfully set up my Private Assembly for my plugins of my executable, like described here: (This is just an example, my use case is technically the same, but not for plugins as such.)

  • Executable uses application manifest to declare dependentAssembly on plugins assembly
  • plugins subdirectory contains plugins.manifest
  • plugins.manifest declares assemblyIdentity with files listing the plugin DLL(s) (say, easyplug1.dll and xplug2.dll)

What I don't quite get, and haven't yet found any direct explanation, is what about DLLs that the DLLs in the Private Assembly depend upon? Where should they be located, how are they found?

Example: The xplug2.dll, which is 3rd party itself needs the 3rd party dll xbase.dll. Naturally, xbase.dll is simply also deployed in the plugins directory. Is this enough? Does the Private Assembly need to list DLLs that are only used transitively by the (executable) module declaring its dependency on the plugins assembly?


Partial answer so far by trial and error:

(A) It seems all DLLs, also those only used from other "plugin" DLLs must be listed in the Private Assembly manifest -- i.e. essentially one should list all DLL files in the plugins assembly directory.

(A.1) Any not-listed DLL will not be found in the directory, even if it's referenced from a DLL within the same subdirectory.

(A.2) I assume this to be due to all the DLL loading machinery using the (only) custom Activation Context from the executable, and if the DLL is not found there, it seems to search from within the executable directory.

(A.3) I tried looking at the dependency chain with the latest version of Dependency Walker (2.2.10011), but it seems it can't handle this transitive scenario at all: Primary dependencies are are shown correctly, but transitive secondary dependencies are not resolved from the manifest, but relative to the base directory. (Seems it follows plain LoadLibrary semantics for the transient ones.)


File layout:

...\base\app.exe 
    // - contains Application Manifest declaring dependency on `plugins`
    // - Loads xplug2.dll

...\base\plugins\xplug2.dll
    // - Loads xbase.dll (which is only used by xplug2.dll internally)

...\base\plugins\xbase.dll

...\base\plugins\plugins.manifest
    // - lists xplug2.dll (for sure)
    // - *seems* to need to list also xbase.dll

1

1 Answers

1
votes

The simple answer is, any "raw" dlls that are not part of an assembly, will be searched for using the applications activation context and/or default dll search rules. And the dll search path includes the application folder, but not any folders that dll's were found in (i.e. a dll can never expect to load another dll that is incidentally in the same folder).

So, for example, if a dll in your assembly required openssl.dll, then it would search first in the application.exe's folder, NOT your private assembly folder unless you specifically, explicitly, added openssl to your private assembly.

the answer is to explicitly add openssl.dll to the private assembly (which incidentally helps protect the integrity of the application should a different dll - in a different assembly - require a different version of openssl.dll)

In your case, you could have two different private assemblies, each using a private version of xbase.dll - where the two different xbase.dlls could be quite incompatible.