mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
4.4 KiB
161 lines
4.4 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.ComponentModel.Design; |
|
using System.IO; |
|
using System.Linq; |
|
|
|
using Microsoft.VisualStudio.Shell; |
|
|
|
using Mono.Cecil; |
|
|
|
using DTEConstants = EnvDTE.Constants; |
|
|
|
namespace ICSharpCode.ILSpy.AddIn.Commands |
|
{ |
|
public class DetectedReference |
|
{ |
|
public DetectedReference(string name, string assemblyFile, bool isProjectReference) |
|
{ |
|
this.Name = name; |
|
this.AssemblyFile = assemblyFile; |
|
this.IsProjectReference = isProjectReference; |
|
} |
|
|
|
public string Name { get; private set; } |
|
public string AssemblyFile { get; private set; } |
|
public bool IsProjectReference { get; private set; } |
|
} |
|
|
|
abstract class ILSpyCommand |
|
{ |
|
protected ILSpyAddInPackage owner; |
|
|
|
protected ILSpyCommand(ILSpyAddInPackage owner, uint id) |
|
{ |
|
ThreadHelper.ThrowIfNotOnUIThread(); |
|
|
|
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", "ILSpy.exe"); |
|
} |
|
|
|
protected void OpenAssembliesInILSpy(ILSpyParameters parameters) |
|
{ |
|
ThreadHelper.ThrowIfNotOnUIThread(); |
|
|
|
if (parameters == null) |
|
return; |
|
|
|
foreach (string assemblyFileName in parameters.AssemblyFileNames) |
|
{ |
|
if (!File.Exists(assemblyFileName)) |
|
{ |
|
owner.ShowMessage("Could not find assembly '{0}', please ensure the project and all references were built correctly!", assemblyFileName); |
|
return; |
|
} |
|
} |
|
|
|
var ilspyExe = new ILSpyInstance(parameters); |
|
ilspyExe.Start(); |
|
} |
|
|
|
protected Dictionary<string, DetectedReference> GetReferences(Microsoft.CodeAnalysis.Project parentProject) |
|
{ |
|
ThreadHelper.ThrowIfNotOnUIThread(); |
|
|
|
var dict = new Dictionary<string, DetectedReference>(); |
|
foreach (var reference in parentProject.MetadataReferences) |
|
{ |
|
using (var assemblyDef = AssemblyDefinition.ReadAssembly(reference.Display)) |
|
{ |
|
string assemblyName = assemblyDef.Name.Name; |
|
string resolvedAssemblyFile = AssemblyFileFinder.FindAssemblyFile(assemblyDef, reference.Display); |
|
dict.Add(assemblyName, new DetectedReference(assemblyName, resolvedAssemblyFile, false)); |
|
} |
|
} |
|
foreach (var projectReference in parentProject.ProjectReferences) |
|
{ |
|
var roslynProject = owner.Workspace.CurrentSolution.GetProject(projectReference.ProjectId); |
|
if (roslynProject != null) |
|
{ |
|
var project = FindProject(owner.DTE.Solution.Projects.OfType<EnvDTE.Project>(), roslynProject.FilePath); |
|
if (project != null) |
|
{ |
|
dict.Add(roslynProject.AssemblyName, |
|
new DetectedReference(roslynProject.AssemblyName, Utils.GetProjectOutputAssembly(project, roslynProject), true)); |
|
} |
|
} |
|
} |
|
return dict; |
|
} |
|
|
|
protected EnvDTE.Project FindProject(IEnumerable<EnvDTE.Project> projects, string projectFile) |
|
{ |
|
ThreadHelper.ThrowIfNotOnUIThread(); |
|
|
|
foreach (var project in projects) |
|
{ |
|
switch (project.Kind) |
|
{ |
|
case DTEConstants.vsProjectKindSolutionItems: |
|
// This is a solution folder -> search in sub-projects |
|
var subProject = FindProject( |
|
project.ProjectItems.OfType<EnvDTE.ProjectItem>().Select(pi => pi.SubProject).OfType<EnvDTE.Project>(), |
|
projectFile); |
|
if (subProject != null) |
|
return subProject; |
|
break; |
|
|
|
case DTEConstants.vsProjectKindUnmodeled: |
|
// Skip unloaded projects completely |
|
break; |
|
|
|
default: |
|
// Match by project's file name |
|
if (project.FileName == projectFile) |
|
return project; |
|
break; |
|
} |
|
} |
|
|
|
return null; |
|
} |
|
} |
|
|
|
class OpenILSpyCommand : ILSpyCommand |
|
{ |
|
static OpenILSpyCommand instance; |
|
|
|
public OpenILSpyCommand(ILSpyAddInPackage owner) |
|
: base(owner, PkgCmdIDList.cmdidOpenILSpy) |
|
{ |
|
ThreadHelper.ThrowIfNotOnUIThread(); |
|
} |
|
|
|
protected override void OnExecute(object sender, EventArgs e) |
|
{ |
|
new ILSpyInstance().Start(); |
|
} |
|
|
|
internal static void Register(ILSpyAddInPackage owner) |
|
{ |
|
ThreadHelper.ThrowIfNotOnUIThread(); |
|
|
|
instance = new OpenILSpyCommand(owner); |
|
} |
|
} |
|
}
|
|
|