Beispiel #1
0
        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();
                }
        }
        public void AnalyzeShouldNotReturnSystemAssembliesWhenFlagIsSet()
        {
            var altOptions = new VisualizerOptions(true, false, "");
            var result     = DependencyAnalyzer.Analyze(filesToAnalyse, null, logger, altOptions);

            Assert.DoesNotContain(result.Assemblies.Values, x => x.AssemblyName.Name == "mscorlib");
            Assert.DoesNotContain(result.Assemblies.Values, x => x.AssemblyName.Name == "netstandard");
            Assert.DoesNotContain(result.Assemblies.Values, x => x.AssemblyName.Name == "System");
        }
Beispiel #3
0
        private static void Visualize(VisualizerOptions options)
        {
            var words = File.ReadAllLines(options.TagsFileName);

            var layouter = new CircularCloudLayouter(Center);
            var tags     = words.Select(word =>
            {
                var font = new Font(FontFamily.GenericSansSerif, Random.Next(MinFontSize, MaxFontSize));
                var size = TextRenderer.MeasureText(word, font);
                var rect = layouter.PutNextRectangle(size);
                return(new Tag(rect, word, font));
            });

            using (var bitmap = CloudVizualizer.DrawTags(tags, new Size(Width, Height), Color.Green))
            {
                bitmap.Save(options.ImageFileName);
            }
        }
Beispiel #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}");
        }
        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);
                }
            }
        }
Beispiel #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));
     }
 }
Beispiel #7
0
        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();
        }
Beispiel #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();
            }
        }
Beispiel #9
0
        public static int Main(string[] args)
        {
            var commandLineApplication = new CommandLineApplication(throwOnUnexpectedArg: true);
            var directoryOrFile        = commandLineApplication.Argument("directoryOrFile", "The directory to search for assemblies or file path to a single assembly");

            var silent = commandLineApplication.Option("-s|--silent", "Do not show any message, only warnings and errors will be shown.", CommandOptionType.NoValue);

            var nonsystem            = commandLineApplication.Option("-n|--nonsystem", "Ignore 'System' assemblies", CommandOptionType.NoValue);
            var all                  = commandLineApplication.Option("-a|--all", "List all assemblies and references.", CommandOptionType.NoValue);
            var referencedStartsWith = commandLineApplication.Option("-rsw|--referencedstartswith", "Referenced Assembly should start with <string>. Will only analyze assemblies if their referenced assemblies starts with the given value.", CommandOptionType.SingleValue);
            var excludeAssemblies    = commandLineApplication.Option("-e|--exclude", "A partial assembly name which should be excluded. This option can be provided multiple times", CommandOptionType.MultipleValue);

            var includeSubDirectories = commandLineApplication.Option("-i|--includesub", "Include subdirectories in search", CommandOptionType.NoValue);
            var configurationFile     = commandLineApplication.Option("-c|--configurationFile", "Use the binding redirects of the given configuration file (Web.config or App.config)", CommandOptionType.SingleValue);
            var failOnMissing         = commandLineApplication.Option("-f|--failOnMissing", "Whether to exit with an error code when AsmSpy detected Assemblies which could not be found", CommandOptionType.NoValue);

            var dependencyVisualizers = GetDependencyVisualizers();

            foreach (var visualizer in dependencyVisualizers)
            {
                visualizer.CreateOption(commandLineApplication);
            }

            commandLineApplication.HelpOption("-? | -h | --help");

            commandLineApplication.OnExecute(() =>
            {
                try
                {
                    var visualizerOptions = new VisualizerOptions
                    {
                        SkipSystem           = nonsystem.HasValue(),
                        OnlyConflicts        = !all.HasValue(),
                        ReferencedStartsWith = referencedStartsWith.HasValue() ? referencedStartsWith.Value() : string.Empty,
                        Exclude = excludeAssemblies.HasValue() ? excludeAssemblies.Values : new List <string>()
                    };

                    var consoleLogger = new ConsoleLogger(!silent.HasValue());

                    var finalResult = GetFileList(directoryOrFile, includeSubDirectories, consoleLogger)
                                      .Bind(x => GetAppDomainWithBindingRedirects(configurationFile)
                                            .Map(appDomain => DependencyAnalyzer.Analyze(
                                                     x.FileList,
                                                     appDomain,
                                                     consoleLogger,
                                                     visualizerOptions,
                                                     x.RootFileName)))
                                      .Map(result => RunVisualizers(result, consoleLogger, visualizerOptions))
                                      .Bind(FailOnMissingAssemblies);

                    switch (finalResult)
                    {
                    case Failure <bool> fail:
                        consoleLogger.LogError(fail.Message);
                        return(-1);

                    case Success <bool> succeed:
                        return(0);

                    default:
                        throw new InvalidOperationException("Unexpected result type");
                    }

                    DependencyAnalyzerResult RunVisualizers(DependencyAnalyzerResult dependencyAnalyzerResult, ILogger logger, VisualizerOptions options)
                    {
                        foreach (var visualizer in dependencyVisualizers.Where(x => x.IsConfigured()))
                        {
                            visualizer.Visualize(dependencyAnalyzerResult, logger, options);
                        }
                        return(dependencyAnalyzerResult);
                    }

                    Result <bool> FailOnMissingAssemblies(DependencyAnalyzerResult dependencyAnalyzerResult)
                    => failOnMissing.HasValue() && dependencyAnalyzerResult.MissingAssemblies.Any()
                            ? "Missing Assemblies"
                            : Result <bool> .Succeed(true);
                }
                catch (Exception exception)
                {
                    Console.WriteLine(exception.ToString());
                    return(-1);
                }
            });

            try
            {
                if (args == null || args.Length == 0)
                {
                    commandLineApplication.ShowHelp();
                    return(0);
                }

                return(commandLineApplication.Execute(args));
            }
            catch (CommandParsingException cpe)
            {
                Console.WriteLine(cpe.Message);
                commandLineApplication.ShowHelp();
                return(-1);
            }
            catch (Exception)
            {
                return(-1);
            }
        }
Beispiel #10
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();
        }