diff --git a/ILSpy/Analyzers/AnalyzerScope.cs b/ILSpy/Analyzers/AnalyzerScope.cs index 375380d74..f735be46b 100644 --- a/ILSpy/Analyzers/AnalyzerScope.cs +++ b/ILSpy/Analyzers/AnalyzerScope.cs @@ -75,13 +75,8 @@ namespace ICSharpCode.ILSpy.Analyzers public IEnumerable GetAllModules() { - foreach (var module in AssemblyList.GetAssemblies()) - { - var file = module.GetPEFileOrNull(); - if (file == null) - continue; - yield return file; - } + return AssemblyList.GetAllAssemblies().GetAwaiter().GetResult() + .Select(asm => asm.GetPEFileOrNull()); } public IEnumerable GetTypesInScope(CancellationToken ct) @@ -138,7 +133,7 @@ namespace ICSharpCode.ILSpy.Analyzers do { PEFile curFile = toWalkFiles.Pop(); - foreach (var assembly in AssemblyList.GetAssemblies()) + foreach (var assembly in AssemblyList.GetAllAssemblies().GetAwaiter().GetResult()) { ct.ThrowIfCancellationRequested(); bool found = false; diff --git a/ILSpy/AssemblyList.cs b/ILSpy/AssemblyList.cs index f2aa07c5b..e01fc44ed 100644 --- a/ILSpy/AssemblyList.cs +++ b/ILSpy/AssemblyList.cs @@ -110,6 +110,48 @@ namespace ICSharpCode.ILSpy } } + /// + /// Gets all loaded assemblies recursively, including assemblies found in bundles or packages. + /// + public async Task> GetAllAssemblies() + { + var assemblies = GetAssemblies(); + var results = new List(assemblies.Length); + + foreach (var asm in assemblies) + { + var result = await asm.GetLoadResultAsync(); + if (result.Package != null) + { + AddDescendants(result.Package.RootFolder); + } + else if (result.PEFile != null) + { + results.Add(asm); + } + } + + void AddDescendants(PackageFolder folder) + { + foreach (var subFolder in folder.Folders) + { + AddDescendants(subFolder); + } + + foreach (var entry in folder.Entries) + { + if (!entry.Name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) + continue; + var asm = folder.ResolveFileName(entry.Name); + if (asm == null) + continue; + results.Add(asm); + } + } + + return results; + } + public int Count { get { lock (lockObj) @@ -233,6 +275,7 @@ namespace ICSharpCode.ILSpy /// public LoadedAssembly OpenAssembly(string file, bool isAutoLoaded = false) { + file = Path.GetFullPath(file); return OpenAssembly(file, () => { var newAsm = new LoadedAssembly(this, file); newAsm.IsAutoLoaded = isAutoLoaded; @@ -245,6 +288,7 @@ namespace ICSharpCode.ILSpy /// public LoadedAssembly OpenAssembly(string file, Stream stream, bool isAutoLoaded = false) { + file = Path.GetFullPath(file); return OpenAssembly(file, () => { var newAsm = new LoadedAssembly(this, file, stream: Task.FromResult(stream)); newAsm.IsAutoLoaded = isAutoLoaded; @@ -254,7 +298,6 @@ namespace ICSharpCode.ILSpy LoadedAssembly OpenAssembly(string file, Func load) { - file = Path.GetFullPath(file); bool isUIThread = App.Current.Dispatcher.Thread == Thread.CurrentThread; LoadedAssembly asm; diff --git a/ILSpy/Search/SearchPane.cs b/ILSpy/Search/SearchPane.cs index 263678ee6..5ad005cce 100644 --- a/ILSpy/Search/SearchPane.cs +++ b/ILSpy/Search/SearchPane.cs @@ -237,7 +237,7 @@ namespace ICSharpCode.ILSpy MainWindow mainWindow = MainWindow.Instance; searchProgressBar.IsIndeterminate = true; - startedSearch = new RunningSearch(mainWindow.CurrentAssemblyList.GetAssemblies(), searchTerm, + startedSearch = new RunningSearch(await mainWindow.CurrentAssemblyList.GetAllAssemblies(), searchTerm, (SearchMode)searchModeComboBox.SelectedIndex, mainWindow.CurrentLanguage, mainWindow.SessionSettings.FilterSettings.ShowApiLevel); currentSearch = startedSearch; @@ -290,14 +290,14 @@ namespace ICSharpCode.ILSpy sealed class RunningSearch { readonly CancellationTokenSource cts = new CancellationTokenSource(); - readonly LoadedAssembly[] assemblies; + readonly IList assemblies; readonly string[] searchTerm; readonly SearchMode searchMode; readonly Language language; readonly ApiVisibility apiVisibility; public readonly IProducerConsumerCollection resultQueue = new ConcurrentQueue(); - public RunningSearch(LoadedAssembly[] assemblies, string searchTerm, SearchMode searchMode, Language language, ApiVisibility apiVisibility) + public RunningSearch(IList assemblies, string searchTerm, SearchMode searchMode, Language language, ApiVisibility apiVisibility) { this.assemblies = assemblies; this.searchTerm = NativeMethods.CommandLineToArgumentArray(searchTerm); diff --git a/ILSpy/TreeNodes/DerivedTypesEntryNode.cs b/ILSpy/TreeNodes/DerivedTypesEntryNode.cs index c006f2002..6c16c50c6 100644 --- a/ILSpy/TreeNodes/DerivedTypesEntryNode.cs +++ b/ILSpy/TreeNodes/DerivedTypesEntryNode.cs @@ -84,8 +84,7 @@ namespace ICSharpCode.ILSpy.TreeNodes IEnumerable FetchChildren(CancellationToken ct) { // FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread - var assemblies = list.GetAssemblies().Select(node => node.GetPEFileOrNull()).Where(asm => asm != null).ToArray(); - return DerivedTypesTreeNode.FindDerivedTypes(list, type, assemblies, ct); + return DerivedTypesTreeNode.FindDerivedTypes(list, type, ct); } public override void ActivateItem(System.Windows.RoutedEventArgs e)