private void WalkBinary(string binaryPath, MutableSymbol parent, string encodedFrameworkNames) { // Add the binary as a reference to resolve symbols in it MetadataReference reference = MetadataReference.CreateFromFile(binaryPath); CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions( outputKind: OutputKind.ConsoleApplication, reportSuppressedDiagnostics: false); compilationOptions.SetMetadataImportOptions(MetadataImportOptions.All); // Create an empty binary to 'host' the reference CSharpCompilation emptyCompilation = CSharpCompilation.Create("Empty.exe", references: new[] { reference }, options: compilationOptions); // Get the root of the reference specifically ISymbol referenceRootSymbol = emptyCompilation.GetAssemblyOrModuleSymbol(reference); // If this wasn't a managed assembly, don't add anything if (referenceRootSymbol == null) { return; } string assemblyName = null; INamespaceSymbol globalNamespace = null; if (referenceRootSymbol is IAssemblySymbol) { // NOTE: Use the Assembly.Identity.Name specifically as the root to allow VS to identify binaries (potentially) already referenced safely. assemblyName = ((IAssemblySymbol)referenceRootSymbol).Identity.Name; globalNamespace = ((IAssemblySymbol)referenceRootSymbol).GlobalNamespace; } else if (referenceRootSymbol is IModuleSymbol) { assemblyName = Path.GetFileName(binaryPath); globalNamespace = ((IModuleSymbol)referenceRootSymbol).GlobalNamespace; } else { // Unable to crawl if we didn't find an assembly or module Trace.WriteLine(String.Format("ERROR: Unable to crawl binary with root symbol type '{0}'", referenceRootSymbol.GetType().Name)); return; } // Walk the binary MutableSymbol addUnderRoot = parent.AddChild(new MutableSymbol(assemblyName, SymbolType.Assembly)); // Add the target framework [if requested and identifiable] if (this.IncludeFrameworkTargets) { if (!String.IsNullOrEmpty(encodedFrameworkNames)) { addUnderRoot = addUnderRoot.AddChild(new MutableSymbol(encodedFrameworkNames, SymbolType.FrameworkTarget)); } } // PRIVATE ROSLYN: Attempt to build a PDB reader for the binary using (PdbSymbolProvider pdbProvider = PdbSymbolProvider.TryBuildProvider(binaryPath)) { PDB = pdbProvider; WalkNamespace(globalNamespace, addUnderRoot); // Remove the PdbSymbolProvider PDB = null; } }