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 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 GetReferences(Microsoft.CodeAnalysis.Project parentProject) { ThreadHelper.ThrowIfNotOnUIThread(); var dict = new Dictionary(); 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(), 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 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().Select(pi => pi.SubProject).OfType(), 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); } } }