Default search order
Topic Using .Net (CLR Managed) Classes in Win32 Applications described the default .Net assembly search order. The conclusion is that we have two locations where we can place COM-visible .Net assemblies:
- In the application folder
- In the assembly-specific folder
An assembly located in the assembly-specific folder will find referenced .Net assemblies as long as they are located in GAC or in the application folder. Therefore if it does not have any non-global dependencies, this option will work. In this case the CLR manifest file may be a separate XML manifest file located in the application folder. As stated in the above topic, the CLR XML manifest file and the corresponding DLL may not be located in the same folder because .Net will only try the DLL and not the manifest if both are present in the folder.
An assembly located in the application folder will find all global
dependencies as well as those in the application folder. However the manifest
file must be embedded as #1 manifest resource. This is the default behavior or
sxs32cmd /CLR:
command. This avoids additional problems resulting
from COM-visible assemblies referencing each other.
Changing the assembly search locations
It is possible to change the .Net assembly search order by changing the
application configuration file. The application.exe.config
file is
accessed by .Net regardless of whether the main program is managed or not. The
following configuration file will make .Net look for dependencies in the
libraries subfolder of the application folder:
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="libraries"/> </assemblyBinding> </runtime> </configuration>
With this change we can place all dependencies in the libraries folder. We can also place all COM-visible assemblies in the same folder. The corresponding Fusion log contains the following search entries:
LOG: Download of application configuration file was attempted from file:///C:/SxsExample/ExampleProgram.exe.Config. LOG: Found application configuration file (C:\SxsExample\ExampleProgram.exe.Config). LOG: Private path hint found in configuration file: libraries. LOG: Using application configuration file: C:\SxsExample\ExampleProgram.exe.Config LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config. LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind). LOG: Attempting download of new URL file:///C:/SxsExample/classlibrary1.DLL. LOG: Attempting download of new URL file:///C:/SxsExample/classlibrary1/classlibrary1.DLL. LOG: Attempting download of new URL file:///C:/SxsExample/libraries/classlibrary1.DLL. LOG: Assembly download was successful. Attempting setup of file: C:\SxsExample\libraries\classlibrary1.dll
Note that .Net first tries the standard locations: the application folder then the assembly-specific subdirectory. After both checks fail, .Net proceeds to the configured privatePath.
"privatePath" may contain a list of subfolders separated by semicolons. This allows organizing DLLs in logically designed tree of subfolders.