Browse Source

Add basic NugetPackageBrowserDialog

pull/870/head
Siegfried Pammer 8 years ago
parent
commit
3fcdfaab8a
  1. 20
      ILSpy/AssemblyList.cs
  2. 12
      ILSpy/ILSpy.csproj
  3. 116
      ILSpy/LoadedNugetPackage.cs
  4. 37
      ILSpy/MainWindow.xaml.cs
  5. 36
      ILSpy/NugetPackageBrowserDialog.xaml
  6. 86
      ILSpy/NugetPackageBrowserDialog.xaml.cs
  7. 6
      ILSpy/TreeNodes/AssemblyTreeNode.cs

20
ILSpy/AssemblyList.cs

@ -162,6 +162,26 @@ namespace ICSharpCode.ILSpy @@ -162,6 +162,26 @@ namespace ICSharpCode.ILSpy
return newAsm;
}
/// <summary>
/// Opens an assembly from a stream.
/// </summary>
public LoadedAssembly OpenAssembly(string file, Stream stream, bool isAutoLoaded = false)
{
App.Current.Dispatcher.VerifyAccess();
foreach (LoadedAssembly asm in this.assemblies) {
if (file.Equals(asm.FileName, StringComparison.OrdinalIgnoreCase))
return asm;
}
var newAsm = new LoadedAssembly(this, file, stream);
newAsm.IsAutoLoaded = isAutoLoaded;
lock (assemblies) {
this.assemblies.Add(newAsm);
}
return newAsm;
}
/// <summary>
/// Replace the assembly object model from a crafted stream, without disk I/O
/// Returns null if it is not already loaded.

12
ILSpy/ILSpy.csproj

@ -43,6 +43,7 @@ @@ -43,6 +43,7 @@
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
<Reference Include="WindowsBase" />
@ -126,11 +127,16 @@ @@ -126,11 +127,16 @@
<Compile Include="Languages\Language.cs" />
<Compile Include="Languages\Languages.cs" />
<Compile Include="LoadedAssembly.cs" />
<Compile Include="LoadedNugetPackage.cs" />
<Compile Include="NativeMethods.cs" />
<Compile Include="NavigationHistory.cs" />
<Compile Include="NavigationState.cs" />
<Compile Include="Commands\OpenCommand.cs" />
<Compile Include="Commands\OpenFromGacCommand.cs" />
<Compile Include="NugetPackageBrowserDialog.xaml.cs">
<SubType>Code</SubType>
<DependentUpon>NugetPackageBrowserDialog.xaml</DependentUpon>
</Compile>
<Compile Include="OpenFromGacDialog.xaml.cs">
<DependentUpon>OpenFromGacDialog.xaml</DependentUpon>
<SubType>Code</SubType>
@ -292,12 +298,10 @@ @@ -292,12 +298,10 @@
<Page Include="MainWindow.xaml" />
<Page Include="OpenFromGacDialog.xaml" />
<Page Include="OpenListDialog.xaml" />
<Page Include="NugetPackageBrowserDialog.xaml" />
<Page Include="Options\DecompilerSettingsPanel.xaml" />
<Page Include="Options\DisplaySettingsPanel.xaml" />
<Page Include="Options\MiscSettingsPanel.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Options\MiscSettingsPanel.xaml" />
<Page Include="Options\OptionsDialog.xaml" />
<Page Include="SearchPane.xaml" />
<Page Include="TextView\DecompilerTextView.xaml" />

116
ILSpy/LoadedNugetPackage.cs

@ -0,0 +1,116 @@ @@ -0,0 +1,116 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;
using System.IO;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace ICSharpCode.ILSpy
{
public class LoadedNugetPackage : INotifyPropertyChanged
{
public List<Entry> Entries { get; } = new List<Entry>();
public List<Entry> SelectedEntries { get; } = new List<Entry>();
public LoadedNugetPackage(string file)
{
using (var archive = ZipFile.OpenRead(file)) {
foreach (var entry in archive.Entries) {
switch (Path.GetExtension(entry.FullName)) {
case ".dll":
case ".exe":
var memory = new MemoryStream();
entry.Open().CopyTo(memory);
memory.Position = 0;
var e = new Entry(entry.FullName, memory);
e.PropertyChanged += EntryPropertyChanged;
Entries.Add(e);
break;
}
}
}
}
void EntryPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(Entry.IsSelected)) {
var entry = (Entry)sender;
if (entry.IsSelected)
SelectedEntries.Add(entry);
else
SelectedEntries.Remove(entry);
OnPropertyChanged("SelectedEntries");
}
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChanged?.Invoke(this, e);
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class Entry : INotifyPropertyChanged
{
public string Name { get; }
public bool IsSelected {
get { return isSelected; }
set {
if (isSelected != value) {
isSelected = value;
OnPropertyChanged();
}
}
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChanged?.Invoke(this, e);
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
public Stream Stream { get; }
bool isSelected;
public event PropertyChangedEventHandler PropertyChanged;
public Entry(string name, Stream stream)
{
this.Name = name;
this.Stream = stream;
}
}
}

37
ILSpy/MainWindow.xaml.cs

@ -677,7 +677,7 @@ namespace ICSharpCode.ILSpy @@ -677,7 +677,7 @@ namespace ICSharpCode.ILSpy
{
e.Handled = true;
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = ".NET assemblies|*.dll;*.exe;*.winmd|All files|*.*";
dlg.Filter = ".NET assemblies|*.dll;*.exe;*.winmd|Nuget Packages (*.nupkg)|*.nupkg|All files|*.*";
dlg.Multiselect = true;
dlg.RestoreDirectory = true;
if (dlg.ShowDialog() == true) {
@ -695,14 +695,35 @@ namespace ICSharpCode.ILSpy @@ -695,14 +695,35 @@ namespace ICSharpCode.ILSpy
SharpTreeNode lastNode = null;
foreach (string file in fileNames) {
var asm = assemblyList.OpenAssembly(file);
if (asm != null) {
var node = assemblyListTreeNode.FindAssemblyNode(asm);
if (node != null && focusNode) {
treeView.SelectedItems.Add(node);
lastNode = node;
}
switch (Path.GetExtension(file)) {
case ".nupkg":
LoadedNugetPackage package = new LoadedNugetPackage(file);
var selectionDialog = new NugetPackageBrowserDialog(package);
if (selectionDialog.ShowDialog() != true)
break;
foreach (var entry in selectionDialog.SelectedItems) {
var nugetAsm = assemblyList.OpenAssembly("nupkg://" + file + ";" + entry.Name, entry.Stream, true);
if (nugetAsm != null) {
var node = assemblyListTreeNode.FindAssemblyNode(nugetAsm);
if (node != null && focusNode) {
treeView.SelectedItems.Add(node);
lastNode = node;
}
}
}
break;
default:
var asm = assemblyList.OpenAssembly(file);
if (asm != null) {
var node = assemblyListTreeNode.FindAssemblyNode(asm);
if (node != null && focusNode) {
treeView.SelectedItems.Add(node);
lastNode = node;
}
}
break;
}
if (lastNode != null && focusNode)
treeView.FocusNode(lastNode);
}

36
ILSpy/NugetPackageBrowserDialog.xaml

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="ICSharpCode.ILSpy.NugetPackageBrowserDialog" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:ICSharpCode.ILSpy.Controls"
xmlns:treeview="http://icsharpcode.net/sharpdevelop/treeview"
Title="Nuget Package Browser"
Style="{DynamicResource DialogWindow}"
WindowStartupLocation="CenterOwner"
ResizeMode="CanResizeWithGrip"
MinWidth="200"
MinHeight="150"
Height="350"
Width="750">
<Grid
Margin="12,8">
<Grid.RowDefinitions>
<RowDefinition
Height="Auto" />
<RowDefinition
Height="1*" />
<RowDefinition
Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="Select assemblies to open:" Margin="5" />
<ListBox ItemsSource="{Binding Package.Entries}" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right">
<Button IsDefault="True" Margin="2,0" IsEnabled="{Binding HasSelection}" Name="okButton" Click="OKButton_Click">Open</Button>
<Button IsCancel="True" Margin="2,0">Cancel</Button>
</StackPanel>
</Grid>
</Window>

86
ILSpy/NugetPackageBrowserDialog.xaml.cs

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using ICSharpCode.ILSpy.Controls;
using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
/// <summary>
/// Interaction logic for NugetPackageBrowserDialog.xaml
/// </summary>
public partial class NugetPackageBrowserDialog : Window, INotifyPropertyChanged
{
public LoadedNugetPackage Package { get; }
public NugetPackageBrowserDialog()
{
InitializeComponent();
}
public NugetPackageBrowserDialog(LoadedNugetPackage package)
{
InitializeComponent();
this.Package = package;
this.Package.PropertyChanged += Package_PropertyChanged;
DataContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
void Package_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(Package.SelectedEntries)) {
OnPropertyChanged(new PropertyChangedEventArgs("HasSelection"));
}
}
void OKButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
Close();
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChanged?.Invoke(this, e);
}
public Entry[] SelectedItems {
get {
return Package.SelectedEntries.ToArray();
}
}
public bool HasSelection {
get { return SelectedItems.Length > 0; }
}
}
}

6
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -402,7 +402,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -402,7 +402,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
public bool IsEnabled(TextViewContext context)
{
return true;
if (context.SelectedTreeNodes == null)
return false;
return context.SelectedTreeNodes.Where(n => n is AssemblyTreeNode).Any(n => !((AssemblyTreeNode)n).LoadedAssembly.FileName.StartsWith("nupkg://"));
}
public void Execute(TextViewContext context)
@ -411,7 +413,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -411,7 +413,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
return;
foreach (var node in context.SelectedTreeNodes) {
var loadedAssm = ((AssemblyTreeNode)node).LoadedAssembly;
if (!loadedAssm.HasLoadError) {
if (!loadedAssm.HasLoadError && !loadedAssm.FileName.StartsWith("nupkg://")) {
loadedAssm.IsAutoLoaded = false;
node.RaisePropertyChanged("Foreground");
}

Loading…
Cancel
Save