Browse Source

Refactor ILSpy.AddIn and fix some bugs

pull/1108/head
Siegfried Pammer 8 years ago
parent
commit
3581635a2d
  1. 86
      ILSpy.AddIn/Commands/OpenCodeItemCommand.cs
  2. 74
      ILSpy.AddIn/Commands/OpenILSpyCommand.cs
  3. 28
      ILSpy.AddIn/Commands/OpenProjectOutputCommand.cs
  4. 130
      ILSpy.AddIn/Commands/OpenReferenceCommand.cs
  5. 18
      ILSpy.AddIn/ILSpy.AddIn.csproj
  6. 317
      ILSpy.AddIn/ILSpyAddInPackage.cs
  7. 8
      ILSpy.AddIn/source.extension.vsixmanifest

86
ILSpy.AddIn/Commands/OpenCodeItemCommand.cs

@ -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);
}
}
}

74
ILSpy.AddIn/Commands/OpenILSpyCommand.cs

@ -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);
}
}
}

28
ILSpy.AddIn/Commands/OpenProjectOutputCommand.cs

@ -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);
}
}
}

130
ILSpy.AddIn/Commands/OpenReferenceCommand.cs

@ -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);
}
}
}

18
ILSpy.AddIn/ILSpy.AddIn.csproj

@ -40,11 +40,19 @@ @@ -40,11 +40,19 @@
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Design" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="VSSDK.Shell.10" Version="10.0.4" />
<PackageReference Include="VSSDK.DTE.10" Version="10.0.4" />
<PackageReference Include="EnvDTE" Version="8.0.2" />
<PackageReference Include="EnvDTE80" Version="8.0.2" />
<PackageReference Include="Microsoft.CodeAnalysis" Version="2.7.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.7.0" />
<PackageReference Include="Microsoft.VisualStudio.ComponentModelHost" Version="15.6.27413" />
<PackageReference Include="Microsoft.VisualStudio.LanguageServices" Version="2.7.0" />
<PackageReference Include="Microsoft.VisualStudio.Shell.14.0" Version="14.3.25407" />
<PackageReference Include="Mono.Cecil" Version="0.10.0-beta7" />
<PackageReference Include="VSLangProj" Version="7.0.3301" />
</ItemGroup>
<ItemGroup>
@ -55,8 +63,12 @@ @@ -55,8 +63,12 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Guids.cs" />
<Compile Include="CodeElementXmlDocKeyProvider.cs" />
<Compile Include="Commands\OpenCodeItemCommand.cs" />
<Compile Include="Commands\OpenILSpyCommand.cs" />
<Compile Include="Commands\OpenProjectOutputCommand.cs" />
<Compile Include="Commands\OpenReferenceCommand.cs" />
<Compile Include="Guids.cs" />
<Compile Include="Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>

317
ILSpy.AddIn/ILSpyAddInPackage.cs

@ -10,6 +10,9 @@ using System.IO; @@ -10,6 +10,9 @@ using System.IO;
using Mono.Cecil;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.ILSpy.AddIn.Commands;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.LanguageServices;
namespace ICSharpCode.ILSpy.AddIn
{
@ -47,6 +50,13 @@ namespace ICSharpCode.ILSpy.AddIn @@ -47,6 +50,13 @@ namespace ICSharpCode.ILSpy.AddIn
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
}
OleMenuCommandService menuService;
public OleMenuCommandService MenuService => menuService;
VisualStudioWorkspace workspace;
public VisualStudioWorkspace Workspace => workspace;
public EnvDTE80.DTE2 DTE => (EnvDTE80.DTE2)GetGlobalService(typeof(EnvDTE.DTE));
/////////////////////////////////////////////////////////////////////////////
@ -63,309 +73,22 @@ namespace ICSharpCode.ILSpy.AddIn @@ -63,309 +73,22 @@ namespace ICSharpCode.ILSpy.AddIn
base.Initialize();
// Add our command handlers for menu (commands must exist in the .vsct file)
OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if (null != mcs) {
// Create the command for the References context menu.
CommandID menuCommandID = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)PkgCmdIDList.cmdidOpenReferenceInILSpy);
OleMenuCommand menuItem = new OleMenuCommand(OpenReferenceInILSpyCallback, menuCommandID);
menuItem.BeforeQueryStatus += OpenReferenceInILSpyCallback_BeforeQueryStatus;
mcs.AddCommand(menuItem);
this.menuService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
// Create the command for the Project context menu, to open the output assembly.
CommandID menuCommandID2 = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)PkgCmdIDList.cmdidOpenProjectOutputInILSpy);
MenuCommand menuItem2 = new MenuCommand(OpenProjectOutputInILSpyCallback, menuCommandID2);
mcs.AddCommand(menuItem2);
var componentModel = (IComponentModel)this.GetService(typeof(SComponentModel));
this.workspace = componentModel.GetService<VisualStudioWorkspace>();
// Create the command for the code window context menu.
CommandID menuCommandID3 = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)PkgCmdIDList.cmdidOpenCodeItemInILSpy);
OleMenuCommand menuItem3 = new OleMenuCommand(OpenCodeItemInILSpyCallback, menuCommandID3);
menuItem3.BeforeQueryStatus += OpenCodeItemInILSpyCallback_BeforeQueryStatus;
mcs.AddCommand(menuItem3);
if (menuService == null || workspace == null)
return;
// Create the command for the Tools menu item.
CommandID menuCommandID4 = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)PkgCmdIDList.cmdidOpenILSpy);
MenuCommand menuItem4 = new MenuCommand(OpenILSpyCallback, menuCommandID4);
mcs.AddCommand(menuItem4);
}
OpenILSpyCommand.Register(this);
OpenProjectOutputCommand.Register(this);
OpenReferenceCommand.Register(this);
OpenCodeItemCommand.Register(this);
}
#endregion
string[] SupportedItems = new[] {
"Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAProjectItem",
"Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAReferenceItem"
};
private void OpenReferenceInILSpyCallback_BeforeQueryStatus(object sender, EventArgs e)
{
OleMenuCommand command = (OleMenuCommand)sender;
var explorer = ((EnvDTE80.DTE2)GetGlobalService(typeof(EnvDTE.DTE))).ToolWindows.SolutionExplorer;
var items = (object[])explorer.SelectedItems;
if (!items.OfType<EnvDTE.UIHierarchyItem>().Any()) {
command.Visible = false;
} else {
command.Visible = items.OfType<EnvDTE.UIHierarchyItem>().All(i => SupportedItems.Contains(i.Object.GetType().FullName) && HasProperties(((dynamic)i.Object).Properties, "Type", "Version", "ResolvedPath"));
}
}
private void OpenReferenceInILSpyCallback(object sender, EventArgs e)
{
var explorer = ((EnvDTE80.DTE2)GetGlobalService(typeof(EnvDTE.DTE))).ToolWindows.SolutionExplorer;
var items = (object[])explorer.SelectedItems;
foreach (EnvDTE.UIHierarchyItem item in items) {
var reference = GetReference(item.Object);
if (reference == null) {
ShowMessage("No reference information was found in the selection!");
continue;
}
string path = null;
if (!string.IsNullOrEmpty(reference.PublicKeyToken)) {
var token = Utils.HexStringToBytes(reference.PublicKeyToken);
path = GacInterop.FindAssemblyInNetGac(new AssemblyNameReference(reference.Name, reference.Version) { PublicKeyToken = token });
}
if (path == null)
path = reference.Path;
OpenAssembliesInILSpy(new[] { path });
}
}
class ReferenceInfo
{
public string Name { get; set; }
public string PublicKeyToken { get; set; }
public string Path { get; set; }
public Version Version { 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)
{
var projectItem = (EnvDTE.ProjectItem)o;
string referenceType = o.GetType().FullName;
string[] values;
switch (referenceType) {
case "Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAReferenceItem":
case "Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAProjectItem":
values = GetProperties(projectItem.Properties, "Type", "FusionName", "ResolvedPath");
if (values[0] == "Package") {
values = GetProperties(projectItem.Properties, "Name", "Version", "Path");
if (values[0] != null && values[1] != null && values[2] != null) {
return new ReferenceInfo {
Name = values[0],
Path = $"{values[2]}\\{values[0]}.{values[1]}.nupkg"
};
}
} else if (values[2] != null) {
return new ReferenceInfo { Path = values[2] };
} else if (!string.IsNullOrWhiteSpace(values[1])) {
return ReferenceInfo.FromFullName(values[1]);
}
return null;
default:
dynamic obj = o;
// C++
if (referenceType.StartsWith("Microsoft.VisualStudio.PlatformUI", StringComparison.Ordinal)) {
return new ReferenceInfo { Path = projectItem.Name };
}
// F#
if (referenceType.StartsWith("Microsoft.VisualStudio.FSharp", StringComparison.Ordinal)) {
o = projectItem.Object;
}
// C# and VB
return new ReferenceInfo {
Name = obj.Identity,
PublicKeyToken = obj.PublicKeyToken,
Path = obj.Path,
Version = new Version(obj.Version)
};
}
}
private string[] GetProperties(EnvDTE.Properties properties, params string[] names)
{
string[] values = new string[names.Length];
foreach (dynamic p in properties) {
try {
ShowMessage("Name: " + p.Name + ", Value: " + p.Value);
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;
}
private void OpenProjectOutputInILSpyCallback(object sender, EventArgs e)
{
var explorer = ((EnvDTE80.DTE2)GetGlobalService(typeof(EnvDTE.DTE))).ToolWindows.SolutionExplorer;
var items = (object[])explorer.SelectedItems;
foreach (EnvDTE.UIHierarchyItem item in items) {
EnvDTE.Project project = (EnvDTE.Project)item.Object;
OpenProjectInILSpy(project);
}
}
// Called when the menu is popped, determines whether "Open code in ILSpy" option is available.
private void OpenCodeItemInILSpyCallback_BeforeQueryStatus(object sender, EventArgs e)
{
OleMenuCommand menuItem = sender as OleMenuCommand;
if (menuItem != null) {
var document = (EnvDTE.Document)(((EnvDTE80.DTE2)GetGlobalService(typeof(EnvDTE.DTE))).ActiveDocument);
menuItem.Enabled =
(document != null) &&
(document.ProjectItem != null) &&
(document.ProjectItem.ContainingProject != null) &&
(document.ProjectItem.ContainingProject.ConfigurationManager != null) &&
!string.IsNullOrEmpty(document.ProjectItem.ContainingProject.FileName);
}
}
private void OpenCodeItemInILSpyCallback(object sender, EventArgs e)
{
var document = (EnvDTE.Document)(((EnvDTE80.DTE2)GetGlobalService(typeof(EnvDTE.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 OpenCodeItemInILSpy(EnvDTE.CodeElement codeElement)
{
string codeElementKey = CodeElementXmlDocKeyProvider.GetKey(codeElement);
OpenProjectInILSpy(codeElement.ProjectItem.ContainingProject, "/navigateTo:" + codeElementKey);
}
private void OpenILSpyCallback(object sender, EventArgs e)
{
Process.Start(GetILSpyPath());
}
private string GetILSpyPath()
{
var basePath = Path.GetDirectoryName(typeof(ILSpyAddInPackage).Assembly.Location);
return Path.Combine(basePath, "ILSpy.exe");
}
private void OpenProjectInILSpy(EnvDTE.Project project, params string[] arguments)
{
EnvDTE.Configuration config = project.ConfigurationManager.ActiveConfiguration;
var outputFiles = config.OutputGroups.OfType<EnvDTE.OutputGroup>()
.Where(g => g.FileCount > 0 && g.CanonicalName == "Built")
.SelectMany(g => (object[])g.FileURLs).Select(f => f?.ToString())
.Where(CheckExtension).Select(f => f.Substring("file:///".Length)).ToArray();
OpenAssembliesInILSpy(outputFiles, arguments);
}
private bool CheckExtension(string fileName)
{
switch (Path.GetExtension(fileName).ToLowerInvariant()) {
case ".exe":
case ".dll":
return true;
default:
return false;
}
}
private void OpenAssembliesInILSpy(IEnumerable<string> assemblyFileNames, params string[] arguments)
{
foreach (string assemblyFileName in assemblyFileNames) {
if (!File.Exists(assemblyFileName)) {
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));
}
Process.Start(GetILSpyPath(), commandLineArguments);
}
private void ShowMessage(string format, params object[] items)
public void ShowMessage(string format, params object[] items)
{
IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
Guid clsid = Guid.Empty;

8
ILSpy.AddIn/source.extension.vsixmanifest

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<PackageManifest Version="2.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Id="a9120dbe-164a-4891-842f-fb7829273838" Version="1.7.3.0" Language="en-US" Publisher="ic#code" />
<Identity Id="a9120dbe-164a-4891-842f-fb7829273838" Version="1.7.4.0" Language="en-US" Publisher="ic#code" />
<DisplayName>ILSpy</DisplayName>
<Description xml:space="preserve">Integrates the ILSpy decompiler into Visual Studio.</Description>
<MoreInfo>http://www.ilspy.net</MoreInfo>
@ -18,7 +18,11 @@ @@ -18,7 +18,11 @@
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.5,)" />
</Dependencies>
<Assets>
<Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="ILSpy.AddIn" Path="|ILSpy.AddIn|"/>
</Assets>
<Prerequisites>
<Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[15.0,16.0)" DisplayName="Visual Studio core editor" />
<Prerequisite Id="Microsoft.VisualStudio.Component.Roslyn.LanguageServices" Version="[15.0,16.0)" DisplayName="Roslyn Language Services" />
</Prerequisites>
</PackageManifest>

Loading…
Cancel
Save