Using an absolute path in privatePath sensing
In a C # console application, I'm trying to use <probing privatePath=""/> to point to DLLs that are not in my application subdirectories. I use:
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="D:\Library\References" /> </assemblyBinding> </runtime> This does not work because privatePath is looking for subdirectories in my application. Is there a way to use absolute paths this way? If not, what is the best way to point to DLLs that are outside of my application? I also tried using <codebase> with the file:/// path, but still got a System.IO.FileNotFound exception.
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="MyLibrary" publicKeyToken="29989D7A39ACF230" /> <codeBase version="2.0.0.0" href="http://file:///D:/Library/References/NLog.dll"/> </dependentAssembly> </assemblyBinding> </runtime> but still got a System.IO.FileNotFound exception.
Thank!
according to MSDN :
You can use this item only in the machine configuration or publisher policy files that also redirect the assembly version .... If you supply a basic code hint for an assembly that is not with a strong name, the hint should point to the application database or subdirectory of the application database directory .
Probably you tried to apply in app.config ?
and
The directories specified in privatePath must be subdirectories of the application directory.
Use AssemblyResolver instead.
Here is some code that I partially typed from another question and modified for our own use. Unlike related code, it permits the application execution folder, which I have not seen in many other examples. Feel free to trim it and stick to your own absolute path if necessary.
One of the advantages of the assembly solver is that if you have mixed versions of your dlls and want to load the dll from the target folder, and not the one that happens with the application, then this works, but the configuration file method does not.
I have this problem because our application comes with a small utility that is an application updater, and it often needs to refer to newer versions of the DLL than the original application. (The update is updated, then it updates the main application. If they both look at the same libraries, bad things can happen.)
public static class AssemblyResolver { internal static void Hook(params string[] folders) { AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { // Check if the requested assembly is part of the loaded assemblies var loadedAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == args.Name); if (loadedAssembly != null) return loadedAssembly; // This resolver is called when a loaded control tries to load a generated XmlSerializer - We need to discard it. // http://connect.microsoft.com/VisualStudio/feedback/details/88566/bindingfailure-an-assembly-failed-to-load-while-using-xmlserialization var n = new AssemblyName(args.Name); if (n.Name.EndsWith(".xmlserializers", StringComparison.OrdinalIgnoreCase)) return null; // http://stackoverflow.com/questions/4368201/appdomain-currentdomain-assemblyresolve-asking-for-a-appname-resources-assembl if (n.Name.EndsWith(".resources", StringComparison.OrdinalIgnoreCase)) return null; string assy = null; // Get execution folder to use as base folder var rootFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)??""; // Find the corresponding assembly file foreach (var dir in folders) { assy = new[] { "*.dll", "*.exe" }.SelectMany(g => Directory.EnumerateFiles(Path.Combine(rootFolder,dir), g)).FirstOrDefault(f => { try { return n.Name.Equals(AssemblyName.GetAssemblyName(f).Name, StringComparison.OrdinalIgnoreCase); } catch (BadImageFormatException) { return false; /* Bypass assembly is not a .net exe */ } catch (Exception ex) { // Logging etc here throw; } }); if (assy != null) return Assembly.LoadFrom(assy); } // More logging for failure here return null; }; } } Call this early on by providing a list of paths used to resolve the assembly.
AssemblyResolver.Hook("upglib","myOtherFolder");