From 43975c2a7799c905a6f9a63182f680395bdc7c59 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Thu, 21 Sep 2017 23:03:44 +0200 Subject: [PATCH] [ILSpy.AddIn] Add support for new assembly, project and package references. --- ILSpy.AddIn/ILSpyAddInPackage.cs | 71 ++++++++++++++++++++++++++++++++ ILSpy/MainWindow.xaml.cs | 35 ++++++++++------ 2 files changed, 94 insertions(+), 12 deletions(-) diff --git a/ILSpy.AddIn/ILSpyAddInPackage.cs b/ILSpy.AddIn/ILSpyAddInPackage.cs index 8a5a88da4..6a78eaf9d 100644 --- a/ILSpy.AddIn/ILSpyAddInPackage.cs +++ b/ILSpy.AddIn/ILSpyAddInPackage.cs @@ -8,6 +8,7 @@ using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Shell; using System.IO; using Mono.Cecil; +using System.Collections.Generic; namespace ICSharpCode.ILSpy.AddIn { @@ -99,6 +100,10 @@ namespace ICSharpCode.ILSpy.AddIn foreach (EnvDTE.UIHierarchyItem item in items) { var reference = GetReference(item.Object); + if (reference.Project != null) { + OpenProjectInILSpy(reference.Project); + continue; + } string path = null; if (!string.IsNullOrEmpty(reference.PublicKeyToken)) { var token = Utils.HexStringToBytes(reference.PublicKeyToken); @@ -116,6 +121,17 @@ namespace ICSharpCode.ILSpy.AddIn public string PublicKeyToken { get; set; } public string Path { get; set; } public Version Version { get; set; } + public EnvDTE.Project Project { get; set; } + + internal static ReferenceInfo FromFullName(string fullName) + { + string[] parts = fullName.Split(new[] { ", " }, StringSplitOptions.RemoveEmptyEntries); + return new ReferenceInfo { + Name = parts[0], + Version = new Version(parts[1].Substring("Version=".Length)), + PublicKeyToken = parts[3].Substring("PublicKeyToken=".Length) + }; + } } private ReferenceInfo GetReference(object o) @@ -133,6 +149,43 @@ namespace ICSharpCode.ILSpy.AddIn obj = obj.Object; } + if (referenceType == "Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAReferenceItem") { + var projectItem = (EnvDTE.ProjectItem)o; + foreach (dynamic p in projectItem.Properties) { + try { + switch (p.Name) { + case "FusionName": + if (!string.IsNullOrWhiteSpace(p.Value)) + return ReferenceInfo.FromFullName(p.Value); + break; + case "Project": + var fileName = p.Object.Name; + EnvDTE.Projects projects = ((EnvDTE80.DTE2)GetGlobalService(typeof(EnvDTE.DTE))).Solution.Projects; + foreach (EnvDTE.Project proj in projects) { + if (Path.GetFileName(proj.FileName) == fileName) { + return new ReferenceInfo { + Project = proj, + Name = fileName + }; + } + } + break; + case "Path": + var values = GetProperties(projectItem.Properties, "Type", "Name", "Version", "Path"); + if (values[0] == "Package" && values[1] != null && values[2] != null && values[3] != null) { + return new ReferenceInfo { + Name = values[1], + Path = $"{values[3]}\\{values[1]}.{values[2]}.nupkg" + }; + } + break; + } + } catch { + continue; + } + } + } + // C# and VB return new ReferenceInfo { Name = obj.Identity, @@ -142,6 +195,24 @@ namespace ICSharpCode.ILSpy.AddIn }; } + string[] GetProperties(EnvDTE.Properties properties, params string[] names) + { + string[] values = new string[names.Length]; + foreach (dynamic p in properties) { + try { + for (int i = 0; i < names.Length; i++) { + if (names[i] == p.Name) { + values[i] = p.Value; + break; + } + } + } catch { + continue; + } + } + return values; + } + private void OpenProjectOutputInILSpyCallback(object sender, EventArgs e) { var explorer = ((EnvDTE80.DTE2)GetGlobalService(typeof(EnvDTE.DTE))).ToolWindows.SolutionExplorer; diff --git a/ILSpy/MainWindow.xaml.cs b/ILSpy/MainWindow.xaml.cs index eb98f6dfc..e9c8e3bc7 100644 --- a/ILSpy/MainWindow.xaml.cs +++ b/ILSpy/MainWindow.xaml.cs @@ -247,9 +247,7 @@ namespace ICSharpCode.ILSpy bool HandleCommandLineArguments(CommandLineArguments args) { - foreach (string file in args.AssembliesToLoad) { - commandLineLoadedAssemblies.Add(assemblyList.OpenAssembly(file)); - } + LoadAssemblies(args.AssembliesToLoad, commandLineLoadedAssemblies, false); if (args.Language != null) sessionSettings.FilterSettings.Language = Languages.GetLanguage(args.Language); return true; @@ -692,7 +690,12 @@ namespace ICSharpCode.ILSpy if (focusNode) treeView.UnselectAll(); - + + LoadAssemblies(fileNames, focusNode: focusNode); + } + + void LoadAssemblies(IEnumerable fileNames, List loadedAssemblies = null, bool focusNode = true) + { SharpTreeNode lastNode = null; foreach (string file in fileNames) { switch (Path.GetExtension(file)) { @@ -704,10 +707,14 @@ namespace ICSharpCode.ILSpy foreach (var entry in selectionDialog.SelectedItems) { var nugetAsm = assemblyList.OpenAssembly("nupkg://" + file + ";" + entry.Name, entry.Stream, true); if (nugetAsm != null) { - var node = assemblyListTreeNode.FindAssemblyNode(nugetAsm); - if (node != null && focusNode) { - treeView.SelectedItems.Add(node); - lastNode = node; + if (loadedAssemblies != null) + loadedAssemblies.Add(nugetAsm); + else { + var node = assemblyListTreeNode.FindAssemblyNode(nugetAsm); + if (node != null && focusNode) { + treeView.SelectedItems.Add(node); + lastNode = node; + } } } } @@ -715,10 +722,14 @@ namespace ICSharpCode.ILSpy default: var asm = assemblyList.OpenAssembly(file); if (asm != null) { - var node = assemblyListTreeNode.FindAssemblyNode(asm); - if (node != null && focusNode) { - treeView.SelectedItems.Add(node); - lastNode = node; + if (loadedAssemblies != null) + loadedAssemblies.Add(asm); + else { + var node = assemblyListTreeNode.FindAssemblyNode(asm); + if (node != null && focusNode) { + treeView.SelectedItems.Add(node); + lastNode = node; + } } } break;