/// <summary> /// Constructs the map from assembly string to its filename. /// /// Roslyn doesn't record the relationship between a filename and its assembly /// information, so we need to retrieve this information manually. /// </summary> private void SetReferencePaths() { foreach (var reference in compilation.References.OfType <PortableExecutableReference>()) { try { var refPath = reference.FilePath; /* This method is significantly faster and more lightweight than using * System.Reflection.Assembly.ReflectionOnlyLoadFrom. It is also allows * loading the same assembly from different locations. */ using var pereader = new System.Reflection.PortableExecutable.PEReader(new FileStream(refPath, FileMode.Open, FileAccess.Read, FileShare.Read)); var metadata = pereader.GetMetadata(); string assemblyIdentity; unsafe { var reader = new System.Reflection.Metadata.MetadataReader(metadata.Pointer, metadata.Length); var def = reader.GetAssemblyDefinition(); assemblyIdentity = reader.GetString(def.Name) + " " + def.Version; } extractor.SetAssemblyFile(assemblyIdentity, refPath); } catch (Exception ex) // lgtm[cs/catch-of-all-exceptions] { extractor.Message(new Message("Exception reading reference file", reference.FilePath, null, ex.StackTrace)); } } }