private AssemblyMetadata CreateAssemblyMetadata(FileStream manifestModuleCopyStream, string originalPath, string shadowCopyPath) { // We don't need to use the global metadata cache here since the shadow copy // won't change and is private to us - only users of the same shadow copy provider see it. ImmutableArray <ModuleMetadata> .Builder moduleBuilder = null; bool fault = true; ModuleMetadata manifestModule = null; try { manifestModule = CreateModuleMetadata(manifestModuleCopyStream); string originalDirectory = null, shadowCopyDirectory = null; foreach (string moduleName in manifestModule.GetModuleNames()) { if (moduleBuilder == null) { moduleBuilder = ImmutableArray.CreateBuilder <ModuleMetadata>(); moduleBuilder.Add(manifestModule); originalDirectory = Path.GetDirectoryName(originalPath); shadowCopyDirectory = Path.GetDirectoryName(shadowCopyPath); } FileStream moduleCopyStream = CopyFile( originalPath: Path.Combine(originalDirectory, moduleName), shadowCopyPath: Path.Combine(shadowCopyDirectory, moduleName)); moduleBuilder.Add(CreateModuleMetadata(moduleCopyStream)); } var modules = (moduleBuilder != null) ? moduleBuilder.ToImmutable() : ImmutableArray.Create(manifestModule); fault = false; return(AssemblyMetadata.Create(modules)); } finally { if (fault) { if (manifestModule != null) { manifestModule.Dispose(); } if (moduleBuilder != null) { for (int i = 1; i < moduleBuilder.Count; i++) { moduleBuilder[i].Dispose(); } } } } }
/// <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); }