public List <Assembly> GetAssemblies() { try { string realPath = Path; if (!File.Exists(realPath)) { string xllName = DnaLibrary.XllPath; string localDirectory = System.IO.Path.GetDirectoryName(xllName); if (System.IO.Path.IsPathRooted(realPath)) { // Rooted path -- try locally string fileName = System.IO.Path.GetFileName(realPath); realPath = System.IO.Path.Combine(localDirectory, fileName); } else { // Try a path relative to local directory realPath = System.IO.Path.Combine(localDirectory, realPath); } // Check again if (!File.Exists(realPath)) { // Give up. Debug.Print("Could not find file " + Path); return(new List <Assembly>()); } } if (System.IO.Path.GetExtension(realPath).ToLower() == ".dna") { // Load as a DnaLibrary DnaLibrary lib = DnaLibrary.LoadFrom(realPath); if (lib == null) { // Problems during load. return(new List <Assembly>()); } return(lib.GetAssemblies()); } else { // Load as a regular assembly List <Assembly> list = new List <Assembly>(); list.Add(Assembly.LoadFrom(realPath)); return(list); } } catch (Exception e) { // Assembly could not be loaded. Debug.Print("Assembly load exception for file: " + Path + "\n" + e.ToString()); return(new List <Assembly>()); } }
internal List <ExportedAssembly> GetAssemblies(string pathResolveRoot, DnaLibrary dnaLibrary) { List <ExportedAssembly> list = new List <ExportedAssembly>(); try { string realPath = Path; if (Path.StartsWith("packed:")) { // The ExternalLibrary is packed. // We'll have to load it from resources. string resourceName = Path.Substring(7); if (Path.EndsWith(".DNA", StringComparison.OrdinalIgnoreCase)) { byte[] dnaContent = ExcelIntegration.GetDnaFileBytes(resourceName); DnaLibrary lib = DnaLibrary.LoadFrom(dnaContent, pathResolveRoot); if (lib == null) { Logger.Initialization.Error("External library could not be registered - Path: {0}\r\n - Packed DnaLibrary could not be loaded", Path); return(list); } return(lib.GetAssemblies(pathResolveRoot)); } else { // DOCUMENT: TypeLibPath which is a resource in a library is denoted as fileName.dll\4 // For packed assemblies, we set TypeLibPath="packed:2" string typeLibPath = null; if (!string.IsNullOrEmpty(TypeLibPath) && TypeLibPath.StartsWith("packed:")) { typeLibPath = DnaLibrary.XllPath + @"\" + TypeLibPath.Substring(7); } // It would be nice to check here whether the assembly is loaded already. // But because of the name mangling in the packing we can't easily check. // So we make the following assumptions: // 1. Packed assemblies won't also be loadable from files (else they might be loaded twice) // 2. ExternalLibrary loads will happen before reference loads via AssemblyResolve. // Under these assumptions we should not have assemblies loaded more than once, // even if not checking here. byte[] rawAssembly = ExcelIntegration.GetAssemblyBytes(resourceName); byte[] rawPdb = ExcelIntegration.GetPdbBytes(resourceName); Assembly assembly = ExcelIntegration.LoadFromAssemblyBytes(rawAssembly, rawPdb); list.Add(new ExportedAssembly(assembly, ExplicitExports, ExplicitRegistration, ComServer, false, typeLibPath, dnaLibrary)); return(list); } } if (Uri.IsWellFormedUriString(Path, UriKind.Absolute)) { // Here is support for loading ExternalLibraries from http. Uri uri = new Uri(Path, UriKind.Absolute); if (uri.IsUnc) { realPath = uri.LocalPath; // Will continue to load later with the regular file load part below... } else { string scheme = uri.Scheme.ToLowerInvariant(); if (scheme != "http" && scheme != "file" && scheme != "https") { Logger.Initialization.Error("The ExternalLibrary path {0} is not a valid Uri scheme.", Path); return(list); } else { if (uri.AbsolutePath.EndsWith("dna", StringComparison.InvariantCultureIgnoreCase)) { DnaLibrary lib = DnaLibrary.LoadFrom(uri); if (lib == null) { Logger.Initialization.Error("External library could not be registered - Path: {0} - DnaLibrary could not be loaded" + Path); return(list); } // CONSIDER: Should we add a resolve story for .dna files at Uris? return(lib.GetAssemblies(null)); // No explicit resolve path } else { // Load as a regular assembly - TypeLib not supported. Assembly assembly = ExcelIntegration.LoadFromAssemblyPath(Path); list.Add(new ExportedAssembly(assembly, ExplicitExports, ExplicitRegistration, ComServer, false, null, dnaLibrary)); return(list); } } } } // Keep trying with the current value of realPath. string resolvedPath = DnaLibrary.ResolvePath(realPath, pathResolveRoot); if (resolvedPath == null) { Logger.Initialization.Error("External library could not be registered - Path: {0} - The library could not be found at this location" + Path); return(list); } if (System.IO.Path.GetExtension(resolvedPath).Equals(".DNA", StringComparison.OrdinalIgnoreCase)) { // Load as a DnaLibrary DnaLibrary lib = DnaLibrary.LoadFrom(resolvedPath); if (lib == null) { Logger.Initialization.Error("External library could not be registered - Path: {0} - DnaLibrary could not be loaded" + Path); return(list); } string pathResolveRelative = System.IO.Path.GetDirectoryName(resolvedPath); return(lib.GetAssemblies(pathResolveRelative)); } else { Assembly assembly; // Load as a regular assembly // First check if it is already loaded (e.g. as a reference from another assembly) // DOCUMENT: Some cases might still have assemblies loaded more than once. // E.g. for an assembly that is both ExternalLibrary and references from another assembly, // having the assembly LoadFromBytes and in the file system would load it twice, // because LoadFromBytes here happens before the .NET loaders assembly resolution. string assemblyName = System.IO.Path.GetFileNameWithoutExtension(resolvedPath); assembly = GetAssemblyIfLoaded(assemblyName); if (assembly == null) { // Really have to load it. if (LoadFromBytes) { // We need to be careful here to not re-load the assembly if it had already been loaded, // e.g. as a dependency of an assembly loaded earlier. // In that case we won't be able to have the library 'LoadFromBytes'. byte[] bytes = File.ReadAllBytes(resolvedPath); byte[] pdbBytes = null; string pdbPath = System.IO.Path.ChangeExtension(resolvedPath, "pdb"); if (File.Exists(pdbPath)) { pdbBytes = File.ReadAllBytes(pdbPath); } assembly = ExcelIntegration.LoadFromAssemblyBytes(bytes, pdbBytes); } else { assembly = ExcelIntegration.LoadFromAssemblyPath(resolvedPath); } } string resolvedTypeLibPath = null; if (!string.IsNullOrEmpty(TypeLibPath)) { resolvedTypeLibPath = DnaLibrary.ResolvePath(TypeLibPath, pathResolveRoot); // null is unresolved if (resolvedTypeLibPath == null) { resolvedTypeLibPath = DnaLibrary.ResolvePath(TypeLibPath, System.IO.Path.GetDirectoryName(resolvedPath)); } } else { // Check for .tlb with same name next to resolvedPath string tlbCheck = System.IO.Path.ChangeExtension(resolvedPath, "tlb"); if (System.IO.File.Exists(tlbCheck)) { resolvedTypeLibPath = tlbCheck; } } list.Add(new ExportedAssembly(assembly, ExplicitExports, ExplicitRegistration, ComServer, false, resolvedTypeLibPath, dnaLibrary)); return(list); } } catch (Exception e) { // Assembly could not be loaded. Logger.Initialization.Error(e, "External library could not be registered - Path: {0}", Path); return(list); } }