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"); }
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); } }
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); } } }
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)); } }
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(); }
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} { 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(); } }
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); } }
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(); }