Modifying .Net Assembly Search Order

Help Home How-To

Quick start guide How to guides Advanced topics User interface Side-by-Side License information
Web Home Free evaluation Download the latest version

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:

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:

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="libraries"/>

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.