Browse Source

Handle failed assembly loads.

pull/1/head
Daniel Grunwald 14 years ago
parent
commit
c8ab6a1e05
  1. 2
      ILSpy/ILSpy.csproj
  2. BIN
      ILSpy/Images/AssemblyList.png
  3. BIN
      ILSpy/Images/AssemblyWarning.png
  4. 1
      ILSpy/Images/Images.cs
  5. 11
      ILSpy/TextView/DecompilerTextView.cs
  6. 52
      ILSpy/TreeNodes/AssemblyTreeNode.cs

2
ILSpy/ILSpy.csproj

@ -99,6 +99,8 @@
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Resource Include="Images\AssemblyList.png" />
<Resource Include="Images\AssemblyWarning.png" />
<None Include="Properties\AssemblyInfo.template.cs" /> <None Include="Properties\AssemblyInfo.template.cs" />
<Compile Include="Properties\WPFAssemblyInfo.cs" /> <Compile Include="Properties\WPFAssemblyInfo.cs" />
<Compile Include="MainWindow.xaml.cs"> <Compile Include="MainWindow.xaml.cs">

BIN
ILSpy/Images/AssemblyList.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

BIN
ILSpy/Images/AssemblyWarning.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

1
ILSpy/Images/Images.cs

@ -16,6 +16,7 @@ namespace ICSharpCode.ILSpy
} }
public static readonly BitmapImage Assembly = LoadBitmap("Assembly"); public static readonly BitmapImage Assembly = LoadBitmap("Assembly");
public static readonly BitmapImage AssemblyWarning = LoadBitmap("AssemblyWarning");
public static readonly BitmapImage Library = LoadBitmap("Library"); public static readonly BitmapImage Library = LoadBitmap("Library");
public static readonly BitmapImage Namespace = LoadBitmap("NameSpace"); public static readonly BitmapImage Namespace = LoadBitmap("NameSpace");

11
ILSpy/TextView/DecompilerTextView.cs

@ -20,6 +20,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
@ -27,7 +28,6 @@ using System.Windows.Controls;
using System.Windows.Media.Animation; using System.Windows.Media.Animation;
using System.Windows.Threading; using System.Windows.Threading;
using System.Xml; using System.Xml;
using ICSharpCode.AvalonEdit.Folding; using ICSharpCode.AvalonEdit.Folding;
using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Highlighting.Xshd; using ICSharpCode.AvalonEdit.Highlighting.Xshd;
@ -98,11 +98,16 @@ namespace ICSharpCode.ILSpy.TextView
textEditor.SyntaxHighlighting = language.SyntaxHighlighting; textEditor.SyntaxHighlighting = language.SyntaxHighlighting;
textEditor.Text = textOutput.ToString(); textEditor.Text = textOutput.ToString();
foldingManager.UpdateFoldings(textOutput.Foldings.OrderBy(f => f.StartOffset), -1); foldingManager.UpdateFoldings(textOutput.Foldings.OrderBy(f => f.StartOffset), -1);
} catch (AggregateException ex) { } catch (AggregateException aggregateException) {
textEditor.SyntaxHighlighting = null; textEditor.SyntaxHighlighting = null;
referenceElementGenerator.References = null; referenceElementGenerator.References = null;
definitionLookup = null; definitionLookup = null;
textEditor.Text = string.Join(Environment.NewLine, ex.InnerExceptions.Select(ie => ie.ToString())); // Unpack aggregate exceptions as long as there's only a single exception:
// (assembly load errors might produce nested aggregate exceptions)
Exception ex = aggregateException;
while (ex is AggregateException && (ex as AggregateException).InnerExceptions.Count == 1)
ex = ex.InnerException;
textEditor.Text = ex.ToString();
} }
} else { } else {
try { try {

52
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -43,7 +43,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
readonly Task<AssemblyDefinition> assemblyTask; readonly Task<AssemblyDefinition> assemblyTask;
readonly List<TypeTreeNode> classes = new List<TypeTreeNode>(); readonly List<TypeTreeNode> classes = new List<TypeTreeNode>();
readonly Dictionary<string, NamespaceTreeNode> namespaces = new Dictionary<string, NamespaceTreeNode>(); readonly Dictionary<string, NamespaceTreeNode> namespaces = new Dictionary<string, NamespaceTreeNode>();
readonly SynchronizationContext syncContext;
public AssemblyTreeNode(string fileName, AssemblyList assemblyList) public AssemblyTreeNode(string fileName, AssemblyList assemblyList)
{ {
@ -54,7 +53,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
this.assemblyList = assemblyList; this.assemblyList = assemblyList;
this.assemblyTask = Task.Factory.StartNew<AssemblyDefinition>(LoadAssembly); // requires that this.fileName is set this.assemblyTask = Task.Factory.StartNew<AssemblyDefinition>(LoadAssembly); // requires that this.fileName is set
this.shortName = Path.GetFileNameWithoutExtension(fileName); this.shortName = Path.GetFileNameWithoutExtension(fileName);
this.syncContext = SynchronizationContext.Current;
assemblyTask.ContinueWith(OnAssemblyLoaded, TaskScheduler.FromCurrentSynchronizationContext());
this.LazyLoading = true; this.LazyLoading = true;
} }
@ -64,7 +64,13 @@ namespace ICSharpCode.ILSpy.TreeNodes
} }
public AssemblyDefinition AssemblyDefinition { public AssemblyDefinition AssemblyDefinition {
get { return assemblyTask.Result; } get {
try {
return assemblyTask.Result;
} catch {
return null;
}
}
} }
public override object Text { public override object Text {
@ -72,7 +78,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
} }
public override object Icon { public override object Icon {
get { return Images.Assembly; } get { return assemblyTask.IsFaulted ? Images.AssemblyWarning : Images.Assembly; }
}
public override bool ShowExpander {
get { return !assemblyTask.IsFaulted; }
} }
AssemblyDefinition LoadAssembly() AssemblyDefinition LoadAssembly()
@ -86,17 +96,25 @@ namespace ICSharpCode.ILSpy.TreeNodes
classes.Add(node); classes.Add(node);
assemblyList.RegisterTypeNode(node); assemblyList.RegisterTypeNode(node);
} }
syncContext.Post(
delegate {
if (shortName != assembly.Name.Name) {
shortName = assembly.Name.Name;
RaisePropertyChanged("Text");
}
}, null);
return assembly; return assembly;
} }
void OnAssemblyLoaded(Task<AssemblyDefinition> assemblyTask)
{
if (assemblyTask.IsFaulted) {
RaisePropertyChanged("Icon");
RaisePropertyChanged("ExpandedIcon");
RaisePropertyChanged("ShowExpander");
} else {
AssemblyDefinition assembly = assemblyTask.Result;
if (shortName != assembly.Name.Name) {
shortName = assembly.Name.Name;
RaisePropertyChanged("Text");
}
}
}
sealed class MyAssemblyResolver : IAssemblyResolver sealed class MyAssemblyResolver : IAssemblyResolver
{ {
readonly AssemblyTreeNode parent; readonly AssemblyTreeNode parent;
@ -133,7 +151,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren() protected override void LoadChildren()
{ {
assemblyTask.Wait(); try {
assemblyTask.Wait();
} catch (AggregateException ex) {
return;
}
ModuleDefinition mainModule = assemblyTask.Result.MainModule; ModuleDefinition mainModule = assemblyTask.Result.MainModule;
this.Children.Add(new ReferenceFolderTreeNode(mainModule, this)); this.Children.Add(new ReferenceFolderTreeNode(mainModule, this));
if (mainModule.HasResources) if (mainModule.HasResources)
@ -187,7 +209,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public AssemblyTreeNode LookupReferencedAssembly(string fullName) public AssemblyTreeNode LookupReferencedAssembly(string fullName)
{ {
foreach (AssemblyTreeNode node in assemblyList.Assemblies) { foreach (AssemblyTreeNode node in assemblyList.Assemblies) {
if (fullName.Equals(node.AssemblyDefinition.FullName, StringComparison.OrdinalIgnoreCase)) if (node.AssemblyDefinition != null && fullName.Equals(node.AssemblyDefinition.FullName, StringComparison.OrdinalIgnoreCase))
return node; return node;
} }
@ -209,8 +231,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override FilterResult Filter(FilterSettings settings) public override FilterResult Filter(FilterSettings settings)
{ {
// avoid accessing this.AssemblyDefinition (waiting for background thread) if settings.SearchTerm == null if (settings.SearchTermMatches(shortName))
if (settings.SearchTerm == null || settings.SearchTermMatches(this.AssemblyDefinition.Name.Name))
return FilterResult.Match; return FilterResult.Match;
else else
return FilterResult.Recurse; return FilterResult.Recurse;
@ -218,6 +239,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{ {
// use assemblyTask.Result instead of this.AssemblyDefinition so that load errors are passed on to the caller
language.DecompileAssembly(assemblyTask.Result, fileName, output, options); language.DecompileAssembly(assemblyTask.Result, fileName, output, options);
} }
} }

Loading…
Cancel
Save