private static ImmutableArray <ModuleMetadata> CreateModulesFromFile(string fullPath) { ArrayBuilder <ModuleMetadata> moduleBuilder = null; // if the file isn't an assembly manifest module an error will be reported later ModuleMetadata manifestModule = ModuleMetadata.CreateFromFile(fullPath); string assemblyDir = null; foreach (string moduleName in manifestModule.GetModuleNames()) { if (moduleBuilder == null) { moduleBuilder = ArrayBuilder <ModuleMetadata> .GetInstance(); moduleBuilder.Add(manifestModule); assemblyDir = Path.GetDirectoryName(fullPath); } var module = ModuleMetadata.CreateFromFile(PathUtilities.CombineAbsoluteAndRelativePaths(assemblyDir, moduleName)); moduleBuilder.Add(module); } return((moduleBuilder != null) ? moduleBuilder.ToImmutableAndFree() : ImmutableArray.Create(manifestModule)); }
internal static AssemblyMetadata CreateFromFile(ModuleMetadata manifestModule, string path) { return(new AssemblyMetadata( manifestModule, moduleName => ModuleMetadata.CreateFromFile( Path.Combine(Path.GetDirectoryName(path) ?? "", moduleName) ) )); }
/// <summary> /// Gets or creates metadata for specified file path. /// </summary> /// <param name="fullPath">Full path to an assembly manifest module file or a standalone module file.</param> /// <param name="kind">Metadata kind (assembly or module).</param> /// <returns>Metadata for the specified file.</returns> /// <exception cref="IOException">Error reading file <paramref name="fullPath"/>. See <see cref="Exception.InnerException"/> for details.</exception> public Metadata GetMetadata(string fullPath, MetadataImageKind kind) { if (NeedsShadowCopy(fullPath)) { return(GetMetadataShadowCopyNoCheck(fullPath, kind).Metadata); } FileKey key = FileKey.Create(fullPath); lock (Guard) { CacheEntry <Metadata> existing; if (_noShadowCopyCache.TryGetValue(key, out existing)) { return(existing.Public); } } Metadata newMetadata; if (kind == MetadataImageKind.Assembly) { newMetadata = AssemblyMetadata.CreateFromFile(fullPath); } else { newMetadata = ModuleMetadata.CreateFromFile(fullPath); } // the files are locked (memory mapped) now key = FileKey.Create(fullPath); lock (Guard) { CacheEntry <Metadata> existing; if (_noShadowCopyCache.TryGetValue(key, out existing)) { newMetadata.Dispose(); return(existing.Public); } Metadata publicMetadata = newMetadata.Copy(); _noShadowCopyCache.Add(key, new CacheEntry <Metadata>(publicMetadata, newMetadata)); return(publicMetadata); } }
/// <exception cref="IOException"/> private static ModuleMetadata GetOrCreateModuleFromFile(string fullPath) { ModuleMetadata module = null; // may throw FileKey key = FileKey.Create(fullPath); CachedModule cachedModule; bool existingKey = modulesFromFiles.TryGetValue(key, out cachedModule); if (existingKey && cachedModule.Metadata.TryGetTarget(out module)) { return(module); } // mempy-map the module: module = ModuleMetadata.CreateFromFile(fullPath); // refresh the timestamp (the file may have changed just before we memory-mapped it): bool fault = true; try { key = FileKey.Create(fullPath); fault = false; } finally { if (fault) { module.Dispose(); } } cachedModule = new CachedModule(module); modulesFromFiles[key] = cachedModule; if (!existingKey) { moduleKeys.Add(key); EnableCompactTimer(); } return(module); }
/// <summary> /// Finds all modules of an assembly on a specified path and builds an instance of <see cref="AssemblyMetadata"/> that represents them. /// </summary> /// <param name="path">The full path to the assembly on disk.</param> /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="path"/> is invalid.</exception> /// <exception cref="IOException">Error reading file <paramref name="path"/>. See <see cref="Exception.InnerException"/> for details.</exception> /// <exception cref="NotSupportedException">Reading from a file path is not supported by the platform.</exception> public static AssemblyMetadata CreateFromFile(string path) { return(CreateFromFile(ModuleMetadata.CreateFromFile(path), path)); }