예제 #1
0
파일: XmlExport.cs 프로젝트: xsjames/AsmSpy
        public void Visualize(DependencyAnalyzerResult result, ILogger logger, VisualizerOptions visualizerOptions)
        {
            if (string.IsNullOrWhiteSpace(outputFile))
            {
                logger.LogError("No valid filename specified.");
                return;
            }

            logger.LogMessage($"Exporting to {outputFile}...");

            var settings = new XmlWriterSettings
            {
                Indent      = true,
                IndentChars = "    ",
                CloseOutput = false
            };

            using (var stream = File.Open(outputFile, FileMode.Create, FileAccess.Write, FileShare.Read))
                using (var writer = XmlWriter.Create(stream, settings))
                {
                    writer.WriteStartDocument();
                    WriteAssemblies(writer, result, visualizerOptions);
                    writer.WriteEndDocument();
                }
        }
예제 #2
0
        public void FetchAssemblyList(string directoryPath)
        {
            ConsoleLogger consoleLogger = new ConsoleLogger(true);

            DirectoryInfo directoryInfo = new DirectoryInfo(directoryPath);

            if (!Directory.Exists(directoryPath))
            {
                consoleLogger.LogMessage(string.Format("Directory: '{0}' does not exist.", directoryPath));
                throw new ArgumentException("Cannot process files in directory: " + directoryPath);
            }

            // For each directory inside the directoryPath, analyze its dependencies
            IEnumerable <string> extensionDirs = Directory.EnumerateDirectories(directoryPath);

            foreach (string extensionDir in extensionDirs)
            {
                IDependencyAnalyzer analyzer = new DependencyAnalyzer()
                {
                    DirectoryInfo = new DirectoryInfo(extensionDir)
                };
                DependencyAnalyzerResult result = analyzer.Analyze(consoleLogger);

                // Output results to Console
                IDependencyVisualizer visualizer = new ConsoleVisualizer(result);
                visualizer.Visualize();

                // Export results to file
                IDependencyVisualizer export = new DgmlExport(result, Path.Combine(directoryPath, extensionDir + ".references.dgml"), consoleLogger);
                export.Visualize();
            }

            Console.Out.WriteLine("Finished fetching assemblies");
        }
예제 #3
0
        public virtual void Visualize(DependencyAnalyzerResult result, ILogger logger, VisualizerOptions visualizerOptions)
        {
            if (result.AnalyzedFiles.Count <= 0)
            {
                Console.WriteLine(AsmSpy_CommandLine.No_assemblies_files_found_in_directory);
                return;
            }

            if (visualizerOptions.OnlyConflicts)
            {
                Console.WriteLine(AsmSpy_CommandLine.Detailing_only_conflicting_assembly_references);
            }

            var assemblyGroups = result.Assemblies.Values.GroupBy(x => x.RedirectedAssemblyName);

            foreach (var assemblyGroup in assemblyGroups.OrderBy(i => i.Key.Name))
            {
                var assemblyInfos = assemblyGroup.OrderBy(x => x.AssemblyName.Name).ToList();
                if (visualizerOptions.OnlyConflicts && assemblyInfos.Count <= 1)
                {
                    if (assemblyInfos.Count == 1 && assemblyInfos[0].AssemblySource == AssemblySource.Local)
                    {
                        continue;
                    }

                    if (assemblyInfos.Count <= 0)
                    {
                        continue;
                    }
                }

                Console.ForegroundColor = ConsoleColor.White;
                Console.Write(AsmSpy_CommandLine.Reference);
                Console.ForegroundColor = GetMainNameColor(assemblyInfos);
                Console.WriteLine(AsmSpy_CommandLine.ConsoleVisualizer_Visualize__0_, assemblyGroup.Key);

                foreach (var assemblyInfo in assemblyInfos)
                {
                    VisualizeAssemblyReferenceInfo(assemblyInfo);
                }

                Console.WriteLine();
            }
            Console.ResetColor();
        }
예제 #4
0
        public void Visualize(DependencyAnalyzerResult result, ILogger logger, VisualizerOptions visualizerOptions)
        {
            using (var writer = new StreamWriter(exportFileName))
            {
                writer.WriteLine("digraph {");

                foreach (var assemblyReference in result.Assemblies.Values)
                {
                    if (visualizerOptions.SkipSystem && assemblyReference.IsSystem)
                    {
                        continue;
                    }

                    var redBackground = ", color=red";

                    writer.WriteLine($"    {assemblyReference.AssemblyName.FullName.GetHashCode()} " +
                                     $"[label=\"{assemblyReference.AssemblyName.Name}\\n{assemblyReference.AssemblyName.Version.ToString()}\"" +
                                     $"{(assemblyReference.AssemblySource == AssemblySource.NotFound ? redBackground : string.Empty)}]");
                }

                writer.WriteLine();

                foreach (var assemblyReference in result.Assemblies.Values)
                {
                    if (visualizerOptions.SkipSystem && assemblyReference.IsSystem)
                    {
                        continue;
                    }

                    foreach (var referenceTo in assemblyReference.References)
                    {
                        if (visualizerOptions.SkipSystem && referenceTo.IsSystem)
                        {
                            continue;
                        }

                        writer.WriteLine($"    {assemblyReference.AssemblyName.FullName.GetHashCode()} -> {referenceTo.AssemblyName.FullName.GetHashCode()};");
                    }
                }

                writer.WriteLine("}");
            }
            logger.LogMessage($"Exported to file {exportFileName}");
        }
예제 #5
0
        public void Visualize(DependencyAnalyzerResult result, ILogger logger, VisualizerOptions visualizerOptions)
        {
            foreach (var root in result.Roots)
            {
                WalkDependencies(root);
            }


            void WalkDependencies(IAssemblyReferenceInfo assembly, string tab = "", bool lastParent = true)
            {
                var label = lastParent ? endNodeLabel : nodeLabel;
                var currentForgroundColor = ForegroundColor;

                Write($"{tab}{label}");
                ForegroundColor = SelectConsoleColor(assembly.AssemblySource);

                var alternativeVersion = assembly.AlternativeFoundVersion == null
                    ? ""
                    : $" -> {assembly.AlternativeFoundVersion.AssemblyName.Version.ToString()}";

                WriteLine($"{assembly.AssemblyName.Name} {assembly.AssemblyName.Version.ToString()}{alternativeVersion}");
                ForegroundColor = currentForgroundColor;

                assembly = assembly.AlternativeFoundVersion ?? assembly;

                var count         = 1;
                var totalChildren = assembly.References.Count();

                foreach (var dependency in assembly.References)
                {
                    if (dependency.AssemblySource == AssemblySource.GlobalAssemblyCache && visualizerOptions.SkipSystem)
                    {
                        continue;
                    }
                    var parentLast  = count++ == totalChildren;
                    var parentLabel = lastParent ? tabLabel : continuationLabel;
                    WalkDependencies(dependency, tab + parentLabel, parentLast);
                }
            }
        }
예제 #6
0
 public void Visualize(DependencyAnalyzerResult result, ILogger logger, VisualizerOptions visualizerOptions)
 {
     try
     {
         var document = Generate(result, skipSystem: false);
         using (var writer = XmlWriter.Create(outputFile, new XmlWriterSettings {
             Indent = true
         }))
         {
             document.WriteTo(writer);
         }
         logger.LogMessage(string.Format(CultureInfo.InvariantCulture, "Exported to file {0}", outputFile));
     }
     catch (UnauthorizedAccessException uae)
     {
         logger.LogError(string.Format(CultureInfo.InvariantCulture, "Could not write file {0} due to error {1}", outputFile, uae.Message));
     }
     catch (DirectoryNotFoundException dnfe)
     {
         logger.LogError(string.Format(CultureInfo.InvariantCulture, "Could not write file {0} due to error {1}", outputFile, dnfe.Message));
     }
 }
예제 #7
0
파일: XmlExport.cs 프로젝트: xsjames/AsmSpy
        private void WriteAssemblies(XmlWriter writer, DependencyAnalyzerResult result, VisualizerOptions visualizerOptions)
        {
            writer.WriteStartElement("Assemblies");
            var assemblyGroups = result.Assemblies.Values.GroupBy(x => x.RedirectedAssemblyName);

            foreach (var assemblyGroup in assemblyGroups.OrderBy(i => i.Key.Name))
            {
                if (visualizerOptions.SkipSystem && AssemblyInformationProvider.IsSystemAssembly(assemblyGroup.Key))
                {
                    continue;
                }

                var assemblyInfos = assemblyGroup.OrderBy(x => x.AssemblyName.Name).ToList();
                if (visualizerOptions.OnlyConflicts && assemblyInfos.Count <= 1)
                {
                    if (assemblyInfos.Count == 1 && assemblyInfos[0].AssemblySource == AssemblySource.Local)
                    {
                        continue;
                    }
                    if (assemblyInfos.Count <= 0)
                    {
                        continue;
                    }
                }

                // Got any references? Respect the user's choices here.
                var referenced = assemblyInfos.SelectMany(x => x.ReferencedBy)
                                 .GroupBy(x => x.AssemblyName.Name)
                                 .Where(x => x.Key.ToUpperInvariant().StartsWith(visualizerOptions.ReferencedStartsWith.ToUpperInvariant(), StringComparison.OrdinalIgnoreCase));
                if (!string.IsNullOrEmpty(visualizerOptions.ReferencedStartsWith) && !referenced.Any())
                {
                    continue;
                }

                using (writer.WriteElementScope("Assembly"))
                {
                    writer.WriteAttributeString("Name", assemblyGroup.Key.Name);
                    writer.WriteAttributeString("Version", assemblyGroup.Key.Version.ToString());
                    writer.WriteAttributeString("FullName", assemblyGroup.Key.FullName);

                    foreach (var assemblyInfo in assemblyInfos)
                    {
                        using (writer.WriteElementScope("Reference"))
                        {
                            writer.WriteAttributeString("Source", assemblyInfo.AssemblySource.ToString());
                            if (assemblyInfo.AssemblySource != AssemblySource.NotFound)
                            {
                                writer.WriteAttributeString("Location", assemblyInfo.ReflectionOnlyAssembly.Location);
                            }

                            foreach (var referer in assemblyInfo.ReferencedBy.OrderBy(x => x.AssemblyName.ToString()))
                            {
                                // Skip this referer? Respect the user's choices here.
                                if (!string.IsNullOrEmpty(visualizerOptions.ReferencedStartsWith))
                                {
                                    if (!referer.AssemblyName.Name.ToUpperInvariant().StartsWith(visualizerOptions.ReferencedStartsWith.ToUpperInvariant(), StringComparison.OrdinalIgnoreCase))
                                    {
                                        continue;
                                    }
                                }

                                using (writer.WriteElementScope("Referer"))
                                {
                                    writer.WriteAttributeString("Name", referer.AssemblyName.Name);
                                    writer.WriteAttributeString("Version", referer.AssemblyName.Version.ToString());
                                    writer.WriteAttributeString("FullName", referer.AssemblyName.FullName);
                                }
                            }
                        }
                    }
                }
            }
            writer.WriteEndElement();
        }
예제 #8
0
        public void Visualize(DependencyAnalyzerResult result, ILogger logger, VisualizerOptions visualizerOptions)
        {
            Stream fileStream = null;

            try
            {
                fileStream = File.OpenWrite(_exportFileName);
                using (var dgml = new StreamWriter(fileStream))
                {
                    fileStream = null; // now the StreamWriter owns the stream (fix warning CA2202)

                    dgml.WriteLine(@"<?xml version=""1.0"" encoding=""utf-8""?>");
                    dgml.WriteLine(@"<DirectedGraph Title=""AsmSpy:References"" xmlns=""http://schemas.microsoft.com/vs/2009/dgml"">");

                    dgml.WriteLine(@"<Nodes>");
                    foreach (var assemblyReference in result.Assemblies.Values)
                    {
                        if (visualizerOptions.SkipSystem && assemblyReference.IsSystem)
                        {
                            continue;
                        }

                        var label = !showVersion.HasValue() ? assemblyReference.AssemblyName.Name : $"{assemblyReference.AssemblyName.Name}&#13;{ assemblyReference.AssemblyName.Version}";
                        dgml.WriteLine(Invariant($@"<Node Id=""{assemblyReference.AssemblyName.FullName}"" Label=""{label}"" Category=""Assembly"">"));
                        dgml.WriteLine(Invariant($@"<Category Ref=""{assemblyReference.AssemblySource}"" />"));
                        dgml.WriteLine(@"</Node>");
                    }

                    dgml.WriteLine(@"</Nodes>");

                    dgml.WriteLine(@"<Links>");

                    foreach (var assemblyReference in result.Assemblies.Values)
                    {
                        if (visualizerOptions.SkipSystem && assemblyReference.IsSystem)
                        {
                            continue;
                        }

                        foreach (var referenceTo in assemblyReference.References)
                        {
                            if (visualizerOptions.SkipSystem && referenceTo.IsSystem)
                            {
                                continue;
                            }

                            dgml.WriteLine(Invariant($@"<Link Source=""{assemblyReference.AssemblyName.FullName}"" Target=""{referenceTo.AssemblyName.FullName}"" Category=""Reference"" />"));
                        }
                    }

                    dgml.WriteLine(@"</Links>");

                    dgml.WriteLine(@"<Categories>");
                    dgml.WriteLine(@"<Category Id=""Assembly""/>");
                    dgml.WriteLine(@"<Category Id=""Reference""/>");

                    foreach (var kvp in AssemblySourceColors)
                    {
                        dgml.WriteLine(Invariant($@"<Category Id=""{kvp.Key}"" Label=""{kvp.Key}"" Background=""{ColorTranslator.ToHtml(kvp.Value)}"" IsTag=""True"" />"));
                    }

                    dgml.WriteLine(@"</Categories>");

                    dgml.WriteLine(@"<Styles>");

                    foreach (var kvp in AssemblySourceColors)
                    {
                        dgml.WriteLine(Invariant($@"<Style TargetType=""Node"" GroupLabel=""AssemblySource: {kvp.Key}"" ValueLabel=""Has category"">"));
                        dgml.WriteLine(Invariant($@"<Condition Expression=""HasCategory('{kvp.Key}')"" />"));
                        dgml.WriteLine(Invariant($@"<Setter Property=""Background"" Value=""{ColorTranslator.ToHtml(kvp.Value)}"" />"));
                        dgml.WriteLine(@"</Style>");
                    }

                    dgml.WriteLine(@"</Styles>");

                    dgml.WriteLine(@"</DirectedGraph>");
                }

                logger.LogMessage(Invariant($"Exported to file {_exportFileName}"));
            }
            catch (UnauthorizedAccessException uae)
            {
                logger.LogError(Invariant($"Could not write file {_exportFileName} due to error {uae.Message}"));
            }
            catch (DirectoryNotFoundException dnfe)
            {
                logger.LogError(Invariant($"Could not write file {_exportFileName} due to error {dnfe.Message}"));
            }
            finally
            {
                fileStream?.Dispose();
            }
        }
예제 #9
0
        public static XmlDocument Generate(DependencyAnalyzerResult result, bool skipSystem)
        {
            var document = new XmlDocument();

            document.LoadXml(@"
                  <runtime>
                    <assemblyBinding xmlns=""urn: schemas - microsoft - com:asm.v1"">
                    </assemblyBinding>
                </runtime>");
            var assemblyGroups = result.Assemblies.Values.GroupBy(x => x.AssemblyName);

            foreach (var assemblyGroup in assemblyGroups.OrderBy(i => i.Key.Name))
            {
                if (skipSystem && AssemblyInformationProvider.IsSystemAssembly(assemblyGroup.Key))
                {
                    continue;
                }

                var assemblyInfos = assemblyGroup.OrderBy(x => x.AssemblyName.ToString()).ToList();
                if (assemblyInfos.Count <= 1)
                {
                    if (assemblyInfos.Count == 1 && assemblyInfos[0].AssemblySource == AssemblySource.Local)
                    {
                        continue;
                    }

                    if (assemblyInfos.Count <= 0)
                    {
                        continue;
                    }
                }

                var sortedAssemblies       = assemblyInfos.OrderByDescending(a => a.AssemblyName.Version).ToList();
                var highestAssemblyVersion = sortedAssemblies.Select(a => a.AssemblyName).First().Version;
                var lowestAssemblyVersion  = sortedAssemblies.Select(a => a.AssemblyName).Last().Version;
                var assemblyToUse          = sortedAssemblies.FirstOrDefault(a => a.AssemblySource != AssemblySource.NotFound)?.AssemblyName;
                if (assemblyToUse == null)
                {
                    continue;
                }

                var depedententAssembly = document.CreateElement("dependentAssembly");
                // <assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
                // <bindingRedirect oldVersion="0.0.0.0-2.1.2.4000" newVersion="2.1.2.4000" />
                var assemblyIdentity = document.CreateElement("assemblyIdentity");
                assemblyIdentity.SetAttribute("name", assemblyToUse.Name);
                var publicKeyToken = GetPublicKeyTokenFromAssembly(assemblyToUse);
                if (publicKeyToken != null)
                {
                    assemblyIdentity.SetAttribute("publicKeyToken", publicKeyToken);
                }
                var cultureName = assemblyToUse.CultureName;
                assemblyIdentity.SetAttribute("culture", string.IsNullOrEmpty(cultureName) ? "neutral" : cultureName);
                depedententAssembly.AppendChild(assemblyIdentity);
                var bindingRedirect = document.CreateElement("bindingRedirect");
                bindingRedirect.SetAttribute("oldVersion", Invariant($"{lowestAssemblyVersion}-{highestAssemblyVersion}"));
                bindingRedirect.SetAttribute("newVersion", assemblyToUse.Version.ToString());
                depedententAssembly.AppendChild(bindingRedirect);
                document.DocumentElement.FirstChild.AppendChild(depedententAssembly);
            }

            return(document);
        }