diff --git a/ILSpy/AssemblyList.cs b/ILSpy/AssemblyList.cs index 6fb33acb0..7a1cd6bf8 100644 --- a/ILSpy/AssemblyList.cs +++ b/ILSpy/AssemblyList.cs @@ -42,6 +42,7 @@ namespace ICSharpCode.ILSpy bool dirty; internal readonly ConcurrentDictionary assemblyLookupCache = new ConcurrentDictionary(); + internal readonly ConcurrentDictionary winRTMetadataLookupCache = new ConcurrentDictionary(); /// /// The assemblies in this list. @@ -103,7 +104,7 @@ namespace ICSharpCode.ILSpy void Assemblies_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { - assemblyLookupCache.Clear(); + ClearCache(); // Whenever the assembly list is modified, mark it as dirty // and enqueue a task that saves it once the UI has finished modifying the assembly list. if (!dirty) { @@ -114,12 +115,18 @@ namespace ICSharpCode.ILSpy delegate { dirty = false; AssemblyListManager.SaveList(this); - assemblyLookupCache.Clear(); + ClearCache(); }) ); } } + internal void ClearCache() + { + assemblyLookupCache.Clear(); + winRTMetadataLookupCache.Clear(); + } + /// /// Opens an assembly from disk. /// Returns the existing assembly node if it is already loaded. diff --git a/ILSpy/Languages/Language.cs b/ILSpy/Languages/Language.cs index 708b0fd3c..56eb85561 100644 --- a/ILSpy/Languages/Language.cs +++ b/ILSpy/Languages/Language.cs @@ -127,7 +127,12 @@ namespace ICSharpCode.ILSpy public virtual void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, assembly.FileName); - WriteCommentLine(output, assembly.AssemblyDefinition.FullName); + var name = assembly.AssemblyDefinition.Name; + if ((name.Attributes & (AssemblyAttributes)0x0200) != 0) { + WriteCommentLine(output, name.Name + " [WinRT]"); + } else { + WriteCommentLine(output, name.FullName); + } } public virtual void WriteCommentLine(ITextOutput output, string comment) diff --git a/ILSpy/LoadedAssembly.cs b/ILSpy/LoadedAssembly.cs index c8ffa8165..ffbea4d53 100644 --- a/ILSpy/LoadedAssembly.cs +++ b/ILSpy/LoadedAssembly.cs @@ -135,7 +135,7 @@ namespace ICSharpCode.ILSpy disposed = true; assemblyLoadDisableCount--; // clear the lookup cache since we might have stored the lookups failed due to DisableAssemblyLoad() - MainWindow.Instance.CurrentAssemblyList.assemblyLookupCache.Clear(); + MainWindow.Instance.CurrentAssemblyList.ClearCache(); } } } @@ -151,13 +151,13 @@ namespace ICSharpCode.ILSpy public AssemblyDefinition Resolve(AssemblyNameReference name) { - var node = parent.LookupReferencedAssembly(name.FullName); + var node = parent.LookupReferencedAssembly(name); return node != null ? node.AssemblyDefinition : null; } public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) { - var node = parent.LookupReferencedAssembly(name.FullName); + var node = parent.LookupReferencedAssembly(name); return node != null ? node.AssemblyDefinition : null; } @@ -179,6 +179,17 @@ namespace ICSharpCode.ILSpy return new MyAssemblyResolver(this); } + public LoadedAssembly LookupReferencedAssembly(AssemblyNameReference name) + { + if (name == null) + throw new ArgumentNullException("name"); + if ((name.Attributes & (AssemblyAttributes)0x0200) != 0) { + return assemblyList.winRTMetadataLookupCache.GetOrAdd(name.Name, LookupWinRTMetadata); + } else { + return assemblyList.assemblyLookupCache.GetOrAdd(name.FullName, LookupReferencedAssemblyInternal); + } + } + public LoadedAssembly LookupReferencedAssembly(string fullName) { return assemblyList.assemblyLookupCache.GetOrAdd(fullName, LookupReferencedAssemblyInternal); @@ -214,6 +225,27 @@ namespace ICSharpCode.ILSpy } } + LoadedAssembly LookupWinRTMetadata(string name) + { + foreach (LoadedAssembly asm in assemblyList.GetAssemblies()) { + if (asm.AssemblyDefinition != null && name.Equals(asm.AssemblyDefinition.Name.Name, StringComparison.OrdinalIgnoreCase)) + return asm; + } + if (assemblyLoadDisableCount > 0) + return null; + if (!App.Current.Dispatcher.CheckAccess()) { + // Call this method on the GUI thread. + return (LoadedAssembly)App.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Func(LookupWinRTMetadata), name); + } + + string file = Path.Combine(Environment.SystemDirectory, "WinMetadata", name + ".winmd"); + if (File.Exists(file)) { + return assemblyList.OpenAssembly(file); + } else { + return null; + } + } + public Task ContinueWhenLoaded(Action> onAssemblyLoaded, TaskScheduler taskScheduler) { return this.assemblyTask.ContinueWith(onAssemblyLoaded, taskScheduler); diff --git a/ILSpy/MainWindow.xaml.cs b/ILSpy/MainWindow.xaml.cs index b92d84a24..a63af47d9 100644 --- a/ILSpy/MainWindow.xaml.cs +++ b/ILSpy/MainWindow.xaml.cs @@ -515,7 +515,7 @@ namespace ICSharpCode.ILSpy { e.Handled = true; OpenFileDialog dlg = new OpenFileDialog(); - dlg.Filter = ".NET assemblies|*.dll;*.exe|All files|*.*"; + dlg.Filter = ".NET assemblies|*.dll;*.exe;*.winmd|All files|*.*"; dlg.Multiselect = true; dlg.RestoreDirectory = true; if (dlg.ShowDialog() == true) { diff --git a/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs b/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs index 13704127d..d9d33b755 100644 --- a/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs @@ -63,7 +63,7 @@ namespace ICSharpCode.ILSpy.TreeNodes { var assemblyListNode = parentAssembly.Parent as AssemblyListTreeNode; if (assemblyListNode != null) { - assemblyListNode.Select(assemblyListNode.FindAssemblyNode(parentAssembly.LoadedAssembly.LookupReferencedAssembly(r.FullName))); + assemblyListNode.Select(assemblyListNode.FindAssemblyNode(parentAssembly.LoadedAssembly.LookupReferencedAssembly(r))); e.Handled = true; } } @@ -72,7 +72,7 @@ namespace ICSharpCode.ILSpy.TreeNodes { var assemblyListNode = parentAssembly.Parent as AssemblyListTreeNode; if (assemblyListNode != null) { - var refNode = assemblyListNode.FindAssemblyNode(parentAssembly.LoadedAssembly.LookupReferencedAssembly(r.FullName)); + var refNode = assemblyListNode.FindAssemblyNode(parentAssembly.LoadedAssembly.LookupReferencedAssembly(r)); if (refNode != null) { AssemblyDefinition asm = refNode.LoadedAssembly.AssemblyDefinition; if (asm != null) { @@ -85,7 +85,11 @@ namespace ICSharpCode.ILSpy.TreeNodes public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) { - language.WriteCommentLine(output, r.FullName); + if ((r.Attributes & (AssemblyAttributes)0x0200) != 0) { + language.WriteCommentLine(output, r.Name + " [WinRT]"); + } else { + language.WriteCommentLine(output, r.FullName); + } } } }