Exemplo n.º 1
0
        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;
            }
        }