mirror of https://github.com/icsharpcode/ILSpy.git
7 changed files with 359 additions and 302 deletions
@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
|
||||
using System; |
||||
using System.Linq; |
||||
using Microsoft.VisualStudio.Shell; |
||||
|
||||
namespace ICSharpCode.ILSpy.AddIn.Commands |
||||
{ |
||||
class OpenCodeItemCommand : ILSpyCommand |
||||
{ |
||||
static OpenCodeItemCommand instance; |
||||
|
||||
public OpenCodeItemCommand(ILSpyAddInPackage owner) |
||||
: base(owner, PkgCmdIDList.cmdidOpenCodeItemInILSpy) |
||||
{ |
||||
} |
||||
|
||||
protected override void OnBeforeQueryStatus(object sender, EventArgs e) |
||||
{ |
||||
OleMenuCommand menuItem = sender as OleMenuCommand; |
||||
if (menuItem != null) { |
||||
var document = owner.DTE.ActiveDocument; |
||||
menuItem.Enabled = |
||||
(document != null) && |
||||
(document.ProjectItem != null) && |
||||
(document.ProjectItem.ContainingProject != null) && |
||||
(document.ProjectItem.ContainingProject.ConfigurationManager != null) && |
||||
!string.IsNullOrEmpty(document.ProjectItem.ContainingProject.FileName); |
||||
} |
||||
} |
||||
|
||||
protected override void OnExecute(object sender, EventArgs e) |
||||
{ |
||||
var document = owner.DTE.ActiveDocument; |
||||
var selection = (EnvDTE.TextPoint)((EnvDTE.TextSelection)document.Selection).ActivePoint; |
||||
|
||||
// Search code elements in desired order, working from innermost to outermost.
|
||||
// Should eventually find something, and if not we'll just open the assembly itself.
|
||||
var codeElement = GetSelectedCodeElement(selection, |
||||
EnvDTE.vsCMElement.vsCMElementFunction, |
||||
EnvDTE.vsCMElement.vsCMElementEvent, |
||||
EnvDTE.vsCMElement.vsCMElementVariable, // There is no vsCMElementField, fields are just variables outside of function scope.
|
||||
EnvDTE.vsCMElement.vsCMElementProperty, |
||||
EnvDTE.vsCMElement.vsCMElementDelegate, |
||||
EnvDTE.vsCMElement.vsCMElementEnum, |
||||
EnvDTE.vsCMElement.vsCMElementInterface, |
||||
EnvDTE.vsCMElement.vsCMElementStruct, |
||||
EnvDTE.vsCMElement.vsCMElementClass, |
||||
EnvDTE.vsCMElement.vsCMElementNamespace); |
||||
|
||||
if (codeElement != null) { |
||||
OpenCodeItemInILSpy(codeElement); |
||||
} |
||||
else { |
||||
OpenProjectInILSpy(document.ProjectItem.ContainingProject); |
||||
} |
||||
} |
||||
|
||||
private EnvDTE.CodeElement GetSelectedCodeElement(EnvDTE.TextPoint selection, params EnvDTE.vsCMElement[] elementTypes) |
||||
{ |
||||
foreach (var elementType in elementTypes) { |
||||
var codeElement = selection.CodeElement[elementType]; |
||||
if (codeElement != null) { |
||||
return codeElement; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
private void OpenProjectInILSpy(EnvDTE.Project project, params string[] arguments) |
||||
{ |
||||
var roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == project.FileName); |
||||
OpenAssembliesInILSpy(new[] { roslynProject.OutputFilePath }, arguments); |
||||
} |
||||
|
||||
private void OpenCodeItemInILSpy(EnvDTE.CodeElement codeElement) |
||||
{ |
||||
string codeElementKey = CodeElementXmlDocKeyProvider.GetKey(codeElement); |
||||
OpenProjectInILSpy(codeElement.ProjectItem.ContainingProject, "/navigateTo:" + codeElementKey); |
||||
} |
||||
|
||||
internal static void Register(ILSpyAddInPackage owner) |
||||
{ |
||||
instance = new OpenCodeItemCommand(owner); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.ComponentModel.Design; |
||||
using System.Diagnostics; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
using Microsoft.VisualStudio.Shell; |
||||
|
||||
namespace ICSharpCode.ILSpy.AddIn.Commands |
||||
{ |
||||
abstract class ILSpyCommand |
||||
{ |
||||
protected ILSpyAddInPackage owner; |
||||
|
||||
protected ILSpyCommand(ILSpyAddInPackage owner, uint id) |
||||
{ |
||||
this.owner = owner; |
||||
CommandID menuCommandID = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)id); |
||||
OleMenuCommand menuItem = new OleMenuCommand(OnExecute, menuCommandID); |
||||
menuItem.BeforeQueryStatus += OnBeforeQueryStatus; |
||||
owner.MenuService.AddCommand(menuItem); |
||||
} |
||||
|
||||
protected virtual void OnBeforeQueryStatus(object sender, EventArgs e) |
||||
{ |
||||
} |
||||
|
||||
protected abstract void OnExecute(object sender, EventArgs e); |
||||
|
||||
protected string GetILSpyPath() |
||||
{ |
||||
var basePath = Path.GetDirectoryName(typeof(ILSpyAddInPackage).Assembly.Location); |
||||
return Path.Combine(basePath, "ILSpy.exe"); |
||||
} |
||||
|
||||
protected void OpenAssembliesInILSpy(IEnumerable<string> assemblyFileNames, params string[] arguments) |
||||
{ |
||||
foreach (string assemblyFileName in assemblyFileNames) { |
||||
if (!File.Exists(assemblyFileName)) { |
||||
owner.ShowMessage("Could not find assembly '{0}', please ensure the project and all references were built correctly!", assemblyFileName); |
||||
} |
||||
} |
||||
|
||||
string commandLineArguments = Utils.ArgumentArrayToCommandLine(assemblyFileNames.ToArray()); |
||||
if (arguments != null) { |
||||
commandLineArguments = string.Concat(commandLineArguments, " ", Utils.ArgumentArrayToCommandLine(arguments)); |
||||
} |
||||
|
||||
System.Diagnostics.Process.Start(GetILSpyPath(), commandLineArguments); |
||||
} |
||||
} |
||||
|
||||
class OpenILSpyCommand : ILSpyCommand |
||||
{ |
||||
static OpenILSpyCommand instance; |
||||
|
||||
public OpenILSpyCommand(ILSpyAddInPackage owner) |
||||
: base(owner, PkgCmdIDList.cmdidOpenILSpy) |
||||
{ |
||||
} |
||||
|
||||
protected override void OnExecute(object sender, EventArgs e) |
||||
{ |
||||
System.Diagnostics.Process.Start(GetILSpyPath()); |
||||
} |
||||
|
||||
internal static void Register(ILSpyAddInPackage owner) |
||||
{ |
||||
instance = new OpenILSpyCommand(owner); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
using System; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.ILSpy.AddIn.Commands |
||||
{ |
||||
class OpenProjectOutputCommand : ILSpyCommand |
||||
{ |
||||
static OpenProjectOutputCommand instance; |
||||
|
||||
public OpenProjectOutputCommand(ILSpyAddInPackage owner) |
||||
: base(owner, PkgCmdIDList.cmdidOpenProjectOutputInILSpy) |
||||
{ |
||||
} |
||||
|
||||
protected override void OnExecute(object sender, EventArgs e) |
||||
{ |
||||
if (owner.DTE.SelectedItems.Count != 1) return; |
||||
var project = owner.DTE.SelectedItems.Item(1).Project; |
||||
var roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == project.FileName); |
||||
OpenAssembliesInILSpy(new[] { roslynProject.OutputFilePath }); |
||||
} |
||||
|
||||
internal static void Register(ILSpyAddInPackage owner) |
||||
{ |
||||
instance = new OpenProjectOutputCommand(owner); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,130 @@
@@ -0,0 +1,130 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using EnvDTE; |
||||
using Microsoft.CodeAnalysis; |
||||
using Mono.Cecil; |
||||
using VSLangProj; |
||||
|
||||
namespace ICSharpCode.ILSpy.AddIn.Commands |
||||
{ |
||||
class OpenReferenceCommand : ILSpyCommand |
||||
{ |
||||
static OpenReferenceCommand instance; |
||||
|
||||
public OpenReferenceCommand(ILSpyAddInPackage owner) |
||||
: base(owner, PkgCmdIDList.cmdidOpenReferenceInILSpy) |
||||
{ |
||||
} |
||||
|
||||
protected override void OnExecute(object sender, EventArgs e) |
||||
{ |
||||
var explorer = owner.DTE.ToolWindows.SolutionExplorer; |
||||
var item = ((object[])explorer.SelectedItems).FirstOrDefault() as UIHierarchyItem; |
||||
|
||||
if (item == null) return; |
||||
if (item.Object is Reference reference) { |
||||
var project = reference.ContainingProject; |
||||
var roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == project.FileName); |
||||
var references = GetReferences(roslynProject); |
||||
if (references.TryGetValue(reference.Name, out var path)) |
||||
OpenAssembliesInILSpy(new[] { path }); |
||||
else |
||||
owner.ShowMessage("Could not find reference '{0}'.", reference.Name); |
||||
} else { |
||||
dynamic referenceObject = item.Object; |
||||
var values = GetProperties(referenceObject.Properties, "Type", "FusionName", "ResolvedPath"); |
||||
if (values[0] == "Package") { |
||||
values = GetProperties(referenceObject.Properties, "Name", "Version", "Path"); |
||||
if (values[0] != null && values[1] != null && values[2] != null) { |
||||
OpenAssembliesInILSpy(new[] { $"{values[2]}\\{values[0]}.{values[1]}.nupkg" }); |
||||
return; |
||||
} |
||||
} else if (values[2] != null) { |
||||
OpenAssembliesInILSpy(new[] { $"{values[2]}" }); |
||||
return; |
||||
} else if (!string.IsNullOrWhiteSpace(values[1])) { |
||||
OpenAssembliesInILSpy(new string[] { GacInterop.FindAssemblyInNetGac(AssemblyNameReference.Parse(values[1])) }); |
||||
return; |
||||
} |
||||
owner.ShowMessage("Could not find reference '{0}'.", referenceObject.Name); |
||||
} |
||||
} |
||||
|
||||
private Dictionary<string, string> GetReferences(Microsoft.CodeAnalysis.Project roslynProject) |
||||
{ |
||||
var dict = new Dictionary<string, string>(); |
||||
foreach (var reference in roslynProject.MetadataReferences) { |
||||
using (var assemblyDef = AssemblyDefinition.ReadAssembly(reference.Display)) { |
||||
if (IsReferenceAssembly(assemblyDef)) { |
||||
dict.Add(assemblyDef.Name.Name, GacInterop.FindAssemblyInNetGac(assemblyDef.Name)); |
||||
} else { |
||||
dict.Add(assemblyDef.Name.Name, reference.Display); |
||||
} |
||||
} |
||||
} |
||||
return dict; |
||||
} |
||||
|
||||
private bool IsReferenceAssembly(AssemblyDefinition assemblyDef) |
||||
{ |
||||
return assemblyDef.CustomAttributes.Any(ca => ca.AttributeType.FullName == "System.Runtime.CompilerServices.ReferenceAssemblyAttribute"); |
||||
} |
||||
|
||||
private string[] GetProperties(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 object GetPropertyObject(EnvDTE.Properties properties, string name) |
||||
{ |
||||
foreach (dynamic p in properties) { |
||||
try { |
||||
if (name == p.Name) { |
||||
return p.Object; |
||||
} |
||||
} catch { |
||||
continue; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private bool HasProperties(EnvDTE.Properties properties, params string[] names) |
||||
{ |
||||
return properties.Count > 0 && names.Any(n => HasProperty(properties, n)); |
||||
} |
||||
|
||||
private bool HasProperty(EnvDTE.Properties properties, string name) |
||||
{ |
||||
foreach (dynamic p in properties) { |
||||
try { |
||||
if (name == p.Name) { |
||||
return true; |
||||
} |
||||
} catch { |
||||
continue; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
internal static void Register(ILSpyAddInPackage owner) |
||||
{ |
||||
instance = new OpenReferenceCommand(owner); |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue