using System; using System.Collections.Generic; using System.Text; namespace RDNZLUtil { /// /// An utility class with static methods for RDNZL. /// public class RDNZLUtil { } /// /// The ResolverHelper class can be used to add additional /// paths to search for assemblies in the Load context. It uses /// the AppDomains AssemblyResolveEvent, which is not recommended /// by Microsoft. /// /// In theory, this could be done inside RDNZL, but at least for ACL7 /// (2007-04-26) the application crashes when returning the freshly /// loaded assembly to the AppDomain that fired the event. /// /// An additional trick would here be to not use LoadFile, but instead /// load the raw bytes of the assembly and use mydomain.Load(bytes) instead. /// This avoids having the file locked by the runtime. /// /// /// public class ResolverHelper { private ResolveEventHandler resolver; private AppDomain mydomain; /// /// The list of additional paths to search for a given assembly. /// public List AdditionalPaths = new List(); /// /// Add a directory path to the list of AdditionalPaths in which to search for assemblies /// /// A directory path public void add_AdditionalPaths(String newpath) { if (System.IO.Directory.Exists(newpath)) AdditionalPaths.Add(newpath); else throw new System.IO.DirectoryNotFoundException("Can't add non-existing directory to the ResolverHelper: " + newpath); } /// /// Remove a directory path from the list of AdditionalPaths in which to search for assemblies /// /// A directory path public void remove_AdditionalPaths(String boguspath) { AdditionalPaths.Remove(boguspath); } /// /// Create a ResolverHelper and add its resolver delegate to the AppDomains AssemblyResolveEvent. /// /// An application domain public ResolverHelper(AppDomain domain) { mydomain = domain; resolver = new ResolveEventHandler(this.Resolver); } /// /// Empty constructor adds a ResolverHelper to the current AppDomains AssemblyResolveEvent. /// public ResolverHelper() : this(AppDomain.CurrentDomain) { } /// /// Start using this ResolverHelper to resolve assemblies /// public void Activate() { mydomain.AssemblyResolve += resolver; } /// /// Stop using this ResolverHelper to resolve assemblies /// public void Deactivate() { mydomain.AssemblyResolve -= resolver; } /// /// This is the function that will actually try to find a missed assembly in the /// additional paths. /// /// Normally an AppDomain /// Event args from the failed search, basically the assembly name /// private System.Reflection.Assembly Resolver(Object Sender, System.ResolveEventArgs args) { String assemblyName = args.Name; String fullName = assemblyName + ".dll"; foreach (string path in AdditionalPaths) { String fullPath = path + fullName; if (System.IO.File.Exists(fullPath)) { return System.Reflection.Assembly.LoadFile(fullPath); } } return null; } } }