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