Browse Source

Fixed several issues with "Open in ILSpy" menu shown on non-applicable nodes. Refactored the commands.

pull/1167/head
Andreas Weizel 7 years ago
parent
commit
809354f175
  1. 45
      ILSpy.AddIn/Commands/AssemblyReferenceForILSpy.cs
  2. 53
      ILSpy.AddIn/Commands/NuGetReferenceForILSpy.cs
  3. 2
      ILSpy.AddIn/Commands/OpenCodeItemCommand.cs
  4. 25
      ILSpy.AddIn/Commands/OpenILSpyCommand.cs
  5. 16
      ILSpy.AddIn/Commands/OpenProjectOutputCommand.cs
  6. 135
      ILSpy.AddIn/Commands/OpenReferenceCommand.cs
  7. 54
      ILSpy.AddIn/Commands/ProjectItemForILSpy.cs
  8. 78
      ILSpy.AddIn/Commands/ProjectReferenceForILSpy.cs
  9. 5
      ILSpy.AddIn/ILSpy.AddIn.csproj
  10. 21
      ILSpy.AddIn/ILSpyAddIn.vsct
  11. 12
      ILSpy.AddIn/ILSpyAddInPackage.cs
  12. 50
      ILSpy.AddIn/Utils.cs

45
ILSpy.AddIn/Commands/AssemblyReferenceForILSpy.cs

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VSLangProj;
namespace ICSharpCode.ILSpy.AddIn.Commands
{
/// <summary>
/// Represents an assembly reference item in Solution Explorer, which can be opened in ILSpy.
/// </summary>
class AssemblyReferenceForILSpy
{
Reference reference;
AssemblyReferenceForILSpy(Reference reference)
{
this.reference = reference;
}
/// <summary>
/// Detects whether the given selected item represents a supported project.
/// </summary>
/// <param name="itemData">Data object of selected item to check.</param>
/// <returns><see cref="AssemblyReferenceForILSpy"/> instance or <c>null</c>, if item is not a supported project.</returns>
public static AssemblyReferenceForILSpy Detect(object itemData)
{
return (itemData is Reference reference) ? new AssemblyReferenceForILSpy(reference) : null;
}
/// <summary>
/// If possible retrieves parameters to use for launching ILSpy instance.
/// </summary>
/// <param name="projectReferences">List of current project's references.</param>
/// <returns>Parameters object or <c>null, if not applicable.</c></returns>
public ILSpyParameters GetILSpyParameters(Dictionary<string, string> projectReferences)
{
if (projectReferences.TryGetValue(reference.Name, out var path))
return new ILSpyParameters(new[] { path });
return null;
}
}
}

53
ILSpy.AddIn/Commands/NuGetReferenceForILSpy.cs

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EnvDTE;
namespace ICSharpCode.ILSpy.AddIn.Commands
{
/// <summary>
/// Represents a NuGet package item in Solution Explorer, which can be opened in ILSpy.
/// </summary>
class NuGetReferenceForILSpy
{
ProjectItem projectItem;
NuGetReferenceForILSpy(ProjectItem projectItem)
{
this.projectItem = projectItem;
}
/// <summary>
/// Detects whether the given selected item represents a supported project.
/// </summary>
/// <param name="itemData">Data object of selected item to check.</param>
/// <returns><see cref="NuGetReferenceForILSpy"/> instance or <c>null</c>, if item is not a supported project.</returns>
public static NuGetReferenceForILSpy Detect(object itemData)
{
if (itemData is ProjectItem projectItem) {
var properties = Utils.GetProperties(projectItem.Properties, "Type");
if ((properties[0] as string) == "Package") {
return new NuGetReferenceForILSpy(projectItem);
}
}
return null;
}
/// <summary>
/// If possible retrieves parameters to use for launching ILSpy instance.
/// </summary>
/// <returns>Parameters object or <c>null, if not applicable.</c></returns>
public ILSpyParameters GetILSpyParameters()
{
var properties = Utils.GetProperties(projectItem.Properties, "Name", "Version", "Path");
if (properties[0] != null && properties[1] != null && properties[2] != null) {
return new ILSpyParameters(new[] { $"{properties[2]}\\{properties[0]}.{properties[1]}.nupkg" });
}
return null;
}
}
}

2
ILSpy.AddIn/Commands/OpenCodeItemCommand.cs

@ -47,7 +47,7 @@ namespace ICSharpCode.ILSpy.AddIn.Commands
if (symbol == null) if (symbol == null)
return; return;
var refs = GetReferences(roslynDocument.Project).Select(fn => fn.Value).Where(f => File.Exists(f)).ToArray(); var refs = GetReferences(roslynDocument.Project).Select(fn => fn.Value).Where(f => File.Exists(f)).ToArray();
OpenAssembliesInILSpy(refs, "/navigateTo:" + symbol.GetDocumentationCommentId()); OpenAssembliesInILSpy(new ILSpyParameters(refs, "/navigateTo:" + symbol.GetDocumentationCommentId()));
} }
internal static void Register(ILSpyAddInPackage owner) internal static void Register(ILSpyAddInPackage owner)

25
ILSpy.AddIn/Commands/OpenILSpyCommand.cs

@ -11,6 +11,18 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.AddIn.Commands namespace ICSharpCode.ILSpy.AddIn.Commands
{ {
public class ILSpyParameters
{
public ILSpyParameters(IEnumerable<string> assemblyFileNames, params string[] arguments)
{
this.AssemblyFileNames = assemblyFileNames;
this.Arguments = arguments;
}
public IEnumerable<string> AssemblyFileNames { get; private set; }
public string[] Arguments { get; private set; }
}
abstract class ILSpyCommand abstract class ILSpyCommand
{ {
protected ILSpyAddInPackage owner; protected ILSpyAddInPackage owner;
@ -36,18 +48,21 @@ namespace ICSharpCode.ILSpy.AddIn.Commands
return Path.Combine(basePath, "ILSpy.exe"); return Path.Combine(basePath, "ILSpy.exe");
} }
protected void OpenAssembliesInILSpy(IEnumerable<string> assemblyFileNames, params string[] arguments) protected void OpenAssembliesInILSpy(ILSpyParameters parameters)
{ {
foreach (string assemblyFileName in assemblyFileNames) { if (parameters == null)
return;
foreach (string assemblyFileName in parameters.AssemblyFileNames) {
if (!File.Exists(assemblyFileName)) { if (!File.Exists(assemblyFileName)) {
owner.ShowMessage("Could not find assembly '{0}', please ensure the project and all references were built correctly!", assemblyFileName); owner.ShowMessage("Could not find assembly '{0}', please ensure the project and all references were built correctly!", assemblyFileName);
return; return;
} }
} }
string commandLineArguments = Utils.ArgumentArrayToCommandLine(assemblyFileNames.ToArray()); string commandLineArguments = Utils.ArgumentArrayToCommandLine(parameters.AssemblyFileNames.ToArray());
if (arguments != null) { if (parameters.Arguments != null) {
commandLineArguments = string.Concat(commandLineArguments, " ", Utils.ArgumentArrayToCommandLine(arguments)); commandLineArguments = string.Concat(commandLineArguments, " ", Utils.ArgumentArrayToCommandLine(parameters.Arguments));
} }
System.Diagnostics.Process.Start(GetILSpyPath(), commandLineArguments); System.Diagnostics.Process.Start(GetILSpyPath(), commandLineArguments);

16
ILSpy.AddIn/Commands/OpenProjectOutputCommand.cs

@ -15,16 +15,12 @@ namespace ICSharpCode.ILSpy.AddIn.Commands
protected override void OnExecute(object sender, EventArgs e) protected override void OnExecute(object sender, EventArgs e)
{ {
if (owner.DTE.SelectedItems.Count != 1) return; if (owner.DTE.SelectedItems.Count != 1)
var project = owner.DTE.SelectedItems.Item(1).Project; return;
var roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == project.FileName); var projectItemWrapper = ProjectItemForILSpy.Detect(owner.DTE.SelectedItems.Item(1));
string outputFileName = Path.GetFileName(roslynProject.OutputFilePath); if (projectItemWrapper != null) {
//get the directory path based on the project file. OpenAssembliesInILSpy(projectItemWrapper.GetILSpyParameters(owner));
string projectPath = Path.GetDirectoryName(project.FullName); }
//get the output path based on the active configuration
string projectOutputPath = project.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString();
//combine the project path and output path to get the bin path
OpenAssembliesInILSpy(new[] { Path.Combine(projectPath, projectOutputPath, outputFileName) });
} }
internal static void Register(ILSpyAddInPackage owner) internal static void Register(ILSpyAddInPackage owner)

135
ILSpy.AddIn/Commands/OpenReferenceCommand.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using EnvDTE; using EnvDTE;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.Shell;
using Mono.Cecil; using Mono.Cecil;
using VSLangProj; using VSLangProj;
@ -17,109 +18,70 @@ namespace ICSharpCode.ILSpy.AddIn.Commands
{ {
} }
protected override void OnBeforeQueryStatus(object sender, EventArgs e)
{
if (sender is OleMenuCommand menuItem) {
menuItem.Visible = false;
var selectedItemData = owner.GetSelectedItemsData<object>().FirstOrDefault();
if (selectedItemData == null)
return;
/*
* Assure that we only show the context menu item on items we intend:
* - Project references
* - NuGet package references
*/
if ((AssemblyReferenceForILSpy.Detect(selectedItemData) != null)
|| (ProjectReferenceForILSpy.Detect(selectedItemData) != null)
|| (NuGetReferenceForILSpy.Detect(selectedItemData) != null)) {
menuItem.Visible = true;
}
}
}
protected override void OnExecute(object sender, EventArgs e) protected override void OnExecute(object sender, EventArgs e)
{ {
var explorer = owner.DTE.ToolWindows.SolutionExplorer; var itemObject = owner.GetSelectedItemsData<object>().FirstOrDefault();
var item = ((object[])explorer.SelectedItems).FirstOrDefault() as UIHierarchyItem; if (itemObject == null)
return;
if (item == null) return; var referenceItem = AssemblyReferenceForILSpy.Detect(itemObject);
if (item.Object is Reference reference) { if (referenceItem != null) {
Reference reference = itemObject as Reference;
var project = reference.ContainingProject; var project = reference.ContainingProject;
var roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == project.FileName); var roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == project.FileName);
var references = GetReferences(roslynProject); var references = GetReferences(roslynProject);
var parameters = referenceItem.GetILSpyParameters(references);
if (references.TryGetValue(reference.Name, out var path)) if (references.TryGetValue(reference.Name, out var path))
OpenAssembliesInILSpy(new[] { path }); OpenAssembliesInILSpy(parameters);
else else
owner.ShowMessage("Could not find reference '{0}', please ensure the project and all references were built correctly!", reference.Name); owner.ShowMessage("Could not find reference '{0}', please ensure the project and all references were built correctly!", reference.Name);
} else {
dynamic referenceObject = item.Object;
if (TryGetProjectFileName(referenceObject, out string fileName)) {
var roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == fileName);
var references = GetReferences(roslynProject);
if (references.TryGetValue(referenceObject.Name, out string path)) {
OpenAssembliesInILSpy(new[] { path });
return;
}
} else {
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}', please ensure the project and all references were built correctly!", referenceObject.Name);
}
} }
private bool TryGetProjectFileName(dynamic referenceObject, out string fileName) // Handle NuGet references
{ var nugetRefItem = NuGetReferenceForILSpy.Detect(itemObject);
try { if (nugetRefItem != null) {
fileName = referenceObject.Project.FileName; OpenAssembliesInILSpy(nugetRefItem.GetILSpyParameters());
return true;
} catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException) {
fileName = null;
return false;
}
} }
private string[] GetProperties(Properties properties, params string[] names) // Handle project references
{ var projectRefItem = ProjectReferenceForILSpy.Detect(itemObject);
string[] values = new string[names.Length]; if (projectRefItem != null) {
foreach (dynamic p in properties) { var projectItem = itemObject as ProjectItem;
try { string fileName = projectItem.ContainingProject?.FileName;
for (int i = 0; i < names.Length; i++) { if (!string.IsNullOrEmpty(fileName)) {
if (names[i] == p.Name) { var roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == fileName);
values[i] = p.Value; var references = GetReferences(roslynProject);
break; if (references.TryGetValue(projectItem.Name, out string path)) {
} OpenAssembliesInILSpy(projectRefItem.GetILSpyParameters(references));
} return;
} 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) OpenAssembliesInILSpy(projectRefItem.GetILSpyParameters());
{ return;
foreach (dynamic p in properties) {
try {
if (name == p.Name) {
return true;
}
} catch {
continue;
}
} }
return false;
} }
internal static void Register(ILSpyAddInPackage owner) internal static void Register(ILSpyAddInPackage owner)
@ -127,4 +89,5 @@ namespace ICSharpCode.ILSpy.AddIn.Commands
instance = new OpenReferenceCommand(owner); instance = new OpenReferenceCommand(owner);
} }
} }
} }

54
ILSpy.AddIn/Commands/ProjectItemForILSpy.cs

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EnvDTE;
namespace ICSharpCode.ILSpy.AddIn.Commands
{
/// <summary>
/// Represents a project item in Solution Explorer, which can be opened in ILSpy.
/// </summary>
class ProjectItemForILSpy
{
SelectedItem item;
ProjectItemForILSpy(SelectedItem item)
{
this.item = item;
}
/// <summary>
/// Detects whether the given <see cref="SelectedItem"/> represents a supported project.
/// </summary>
/// <param name="item">Selected item to check.</param>
/// <returns><see cref="ProjectItemForILSpy"/> instance or <c>null</c>, if item is not a supported project.</returns>
public static ProjectItemForILSpy Detect(SelectedItem item)
{
return new ProjectItemForILSpy(item);
}
/// <summary>
/// If possible retrieves parameters to use for launching ILSpy instance.
/// </summary>
/// <param name="owner">Package instance.</param>
/// <returns>Parameters object or <c>null, if not applicable.</c></returns>
public ILSpyParameters GetILSpyParameters(ILSpyAddInPackage owner)
{
var project = item.Project;
var roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == project.FileName);
string outputFileName = Path.GetFileName(roslynProject.OutputFilePath);
// Get the directory path based on the project file.
string projectPath = Path.GetDirectoryName(project.FullName);
// Get the output path based on the active configuration
string projectOutputPath = project.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString();
// Combine the project path and output path to get the bin path
return new ILSpyParameters(new[] { Path.Combine(projectPath, projectOutputPath, outputFileName) });
}
}
}

78
ILSpy.AddIn/Commands/ProjectReferenceForILSpy.cs

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EnvDTE;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.AddIn.Commands
{
/// <summary>
/// Represents a project reference item in Solution Explorer, which can be opened in ILSpy.
/// </summary>
class ProjectReferenceForILSpy
{
ProjectItem projectItem;
string fusionName;
string resolvedPath;
ProjectReferenceForILSpy(ProjectItem projectItem, string fusionName, string resolvedPath)
{
this.projectItem = projectItem;
this.fusionName = fusionName;
this.resolvedPath = resolvedPath;
}
/// <summary>
/// Detects whether the given selected item represents a supported project.
/// </summary>
/// <param name="itemData">Data object of selected item to check.</param>
/// <returns><see cref="ProjectReferenceForILSpy"/> instance or <c>null</c>, if item is not a supported project.</returns>
public static ProjectReferenceForILSpy Detect(object itemData)
{
if (itemData is ProjectItem projectItem) {
var properties = Utils.GetProperties(projectItem.Properties, "FusionName", "ResolvedPath");
string fusionName = properties[0] as string;
string resolvedPath = properties[1] as string;
if ((fusionName != null) || (resolvedPath != null)) {
return new ProjectReferenceForILSpy(projectItem, fusionName, resolvedPath);
}
}
return null;
}
/// <summary>
/// If possible retrieves parameters to use for launching ILSpy instance.
/// </summary>
/// <param name="projectReferences">List of current project's references.</param>
/// <returns>Parameters object or <c>null, if not applicable.</c></returns>
public ILSpyParameters GetILSpyParameters(Dictionary<string, string> projectReferences)
{
string fileName = projectItem.ContainingProject?.FileName;
if (!string.IsNullOrEmpty(fileName)) {
if (projectReferences.TryGetValue(projectItem.Name, out string path)) {
return new ILSpyParameters(new[] { path });
}
}
return null;
}
/// <summary>
/// If possible retrieves parameters to use for launching ILSpy instance.
/// </summary>
/// <returns>Parameters object or <c>null, if not applicable.</c></returns>
public ILSpyParameters GetILSpyParameters()
{
if (resolvedPath != null) {
return new ILSpyParameters(new[] { $"{resolvedPath}" });
} else if (!string.IsNullOrWhiteSpace(fusionName)) {
return new ILSpyParameters(new string[] { GacInterop.FindAssemblyInNetGac(AssemblyNameReference.Parse(fusionName)) });
}
return null;
}
}
}

5
ILSpy.AddIn/ILSpy.AddIn.csproj

@ -63,6 +63,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Commands\AssemblyReferenceForILSpy.cs" />
<Compile Include="Commands\NuGetReferenceForILSpy.cs" />
<Compile Include="Commands\ProjectItemForILSpy.cs" />
<Compile Include="Commands\ProjectReferenceForILSpy.cs" />
<Compile Include="Commands\OpenCodeItemCommand.cs" /> <Compile Include="Commands\OpenCodeItemCommand.cs" />
<Compile Include="Commands\OpenILSpyCommand.cs" /> <Compile Include="Commands\OpenILSpyCommand.cs" />
<Compile Include="Commands\OpenProjectOutputCommand.cs" /> <Compile Include="Commands\OpenProjectOutputCommand.cs" />
@ -100,6 +104,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="ILSpyAddIn.vsct" />
<None Include="source.extension.vsixmanifest"> <None Include="source.extension.vsixmanifest">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</None> </None>

21
ILSpy.AddIn/ILSpyAddIn.vsct

@ -51,6 +51,10 @@
<Group guid="guidILSpyAddInCmdSet" id="OpenILSpyCodeItemGroup" priority="0x0200"> <Group guid="guidILSpyAddInCmdSet" id="OpenILSpyCodeItemGroup" priority="0x0200">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN"/> <Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN"/>
</Group> </Group>
<Group guid="guidILSpyAddInCmdSet" id="OpenILSpyRefGroup" priority="0x0200">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_REFERENCE"/>
</Group>
</Groups> </Groups>
<!--Buttons section. --> <!--Buttons section. -->
@ -83,13 +87,13 @@
</Strings> </Strings>
</Button> </Button>
<Button guid="guidILSpyAddInCmdSet" id="cmdidOpenCodeItemInILSpy" priority="0x0600" type="Button"> <!--<Button guid="guidILSpyAddInCmdSet" id="cmdidOpenCodeItemInILSpy" priority="0x0600" type="Button">
<Parent guid="guidILSpyAddInCmdSet" id="OpenILSpyCodeItemGroup" /> <Parent guid="guidILSpyAddInCmdSet" id="OpenILSpyCodeItemGroup" />
<Icon guid="guidImages" id="bmpLogo" /> <Icon guid="guidImages" id="bmpLogo" />
<Strings> <Strings>
<ButtonText>Open code in ILSpy</ButtonText> <ButtonText>Open code in ILSpy</ButtonText>
</Strings> </Strings>
</Button> </Button>-->
<Button guid="guidILSpyAddInCmdSet" id="cmdidOpenILSpy" priority="0x0600" type="Button"> <Button guid="guidILSpyAddInCmdSet" id="cmdidOpenILSpy" priority="0x0600" type="Button">
<Parent guid="guidILSpyAddInCmdSet" id="OpenILSpyGroup" /> <Parent guid="guidILSpyAddInCmdSet" id="OpenILSpyGroup" />
@ -112,19 +116,6 @@
</Bitmaps> </Bitmaps>
</Commands> </Commands>
<CommandPlacements>
<!--
<CommandPlacement guid="guidILSpyAddInCmdSet" id="cmdidOpenReferenceInILSpy" priority="0x0600">
<Parent guid="guidSHLMainMenu" id="IDG_VS_CTXT_REFERENCE"/>
</CommandPlacement>
-->
<!-- HACK : since there is no special ID for the new .NET Standard 2.0 reference nodes,
use the ITEM_OPEN id and hide the item if not applicable. -->
<CommandPlacement guid="guidILSpyAddInCmdSet" id="cmdidOpenReferenceInILSpy" priority="0x0600">
<Parent guid="guidSHLMainMenu" id="IDG_VS_CTXT_ITEM_OPEN"/>
</CommandPlacement>
</CommandPlacements>
<Symbols> <Symbols>
<!-- This is the package guid. --> <!-- This is the package guid. -->
<GuidSymbol name="guidILSpyAddInPkg" value="{a9120dbe-164a-4891-842f-fb7829273838}" /> <GuidSymbol name="guidILSpyAddInPkg" value="{a9120dbe-164a-4891-842f-fb7829273838}" />

12
ILSpy.AddIn/ILSpyAddInPackage.cs

@ -13,6 +13,7 @@ using System.Linq;
using ICSharpCode.ILSpy.AddIn.Commands; using ICSharpCode.ILSpy.AddIn.Commands;
using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.LanguageServices; using Microsoft.VisualStudio.LanguageServices;
using EnvDTE;
namespace ICSharpCode.ILSpy.AddIn namespace ICSharpCode.ILSpy.AddIn
{ {
@ -109,5 +110,16 @@ namespace ICSharpCode.ILSpy.AddIn
) )
); );
} }
public IEnumerable<T> GetSelectedItemsData<T>()
{
if (DTE.ToolWindows.SolutionExplorer.SelectedItems is IEnumerable<UIHierarchyItem> hierarchyItems) {
foreach (var item in hierarchyItems) {
if (item.Object is T typedItem) {
yield return typedItem;
}
}
}
}
} }
} }

50
ILSpy.AddIn/Utils.cs

@ -1,7 +1,10 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using EnvDTE;
namespace ICSharpCode.ILSpy.AddIn namespace ICSharpCode.ILSpy.AddIn
{ {
@ -111,5 +114,52 @@ namespace ICSharpCode.ILSpy.AddIn
} }
return result; return result;
} }
public static bool TryGetProjectFileName(dynamic referenceObject, out string fileName)
{
try {
fileName = referenceObject.Project.FileName;
return true;
} catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException) {
fileName = null;
return false;
}
}
public static object[] GetProperties(Properties properties, params string[] names)
{
var values = new object[names.Length];
foreach (object p in properties) {
try {
if (p is Property property) {
for (int i = 0; i < names.Length; i++) {
if (names[i] == property.Name) {
values[i] = property.Value;
break;
}
}
}
} catch {
continue;
}
}
return values;
}
public static List<(string, object)> GetAllProperties(Properties properties)
{
var result = new List<(string, object)>();
for (int i = 0; i < properties.Count; i++) {
try {
if (properties.Item(i) is Property p) {
result.Add((p.Name, p.Value));
}
} catch {
continue;
}
}
return result;
}
} }
} }

Loading…
Cancel
Save