One nice approach I've used lately is to add an event handler for the AppDomain's AssemblyResolve event.
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
Then in the event handler method you can load the assembly that was attempted to be resolved using one of the Assembly.Load, Assembly.LoadFrom overrides and return it from the method.
EDIT:
Based on your additional information I think using the technique above, specifically resolving the references to an assembly yourself is the only real approach that is going to work without restructuring your app. What it gives you is that the location of each and every assembly that the CLR fails to resolve can be determined and loaded by your code at runtime... I've used this in similar situations for both pluggable architectures and for an assembly reference integrity scanning tool.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…