From cae002273cd79ccde6da9fe546ba18c0672d95fc Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Fri, 21 Nov 2025 22:38:43 +0800 Subject: [PATCH] Batch calls to `ShellHelper.OpenFolderAndSelectItems` instead of looping `OpenFolderAndSelectItem`. --- .../ExtractPackageEntryContextMenuEntry.cs | 22 ++++++++++++++++++- ILSpy/TreeNodes/AssemblyTreeNode.cs | 5 ++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs b/ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs index e3870cc98..e1209a4af 100644 --- a/ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs +++ b/ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs @@ -124,17 +124,22 @@ namespace ICSharpCode.ILSpy dockWorkspace.RunWithCancellation(ct => Task.Factory.StartNew(() => { AvalonEditTextOutput output = new AvalonEditTextOutput(); Stopwatch stopwatch = Stopwatch.StartNew(); + var writtenFiles = new List(); foreach (var node in nodes) { if (node is AssemblyTreeNode { PackageEntry: { } assembly }) { string fileName = GetFileName(path, isFile, node.Parent, assembly); SaveEntry(output, assembly, fileName); + if (File.Exists(fileName)) + writtenFiles.Add(fileName); } else if (node is ResourceTreeNode { Resource: PackageEntry { } resource }) { string fileName = GetFileName(path, isFile, node.Parent, resource); SaveEntry(output, resource, fileName); + if (File.Exists(fileName)) + writtenFiles.Add(fileName); } else if (node is PackageFolderTreeNode) { @@ -145,11 +150,15 @@ namespace ICSharpCode.ILSpy { string fileName = GetFileName(path, isFile, item.Parent, asm); SaveEntry(output, asm, fileName); + if (File.Exists(fileName)) + writtenFiles.Add(fileName); } else if (item is ResourceTreeNode { Resource: PackageEntry { } entry }) { string fileName = GetFileName(path, isFile, item.Parent, entry); SaveEntry(output, entry, fileName); + if (File.Exists(fileName)) + writtenFiles.Add(fileName); } else if (item is PackageFolderTreeNode) { @@ -161,7 +170,18 @@ namespace ICSharpCode.ILSpy stopwatch.Stop(); output.WriteLine(Resources.GenerationCompleteInSeconds, stopwatch.Elapsed.TotalSeconds.ToString("F1")); output.WriteLine(); - output.AddButton(null, Resources.OpenExplorer, delegate { if (isFile) ShellHelper.OpenFolderAndSelectItem(path); else ShellHelper.OpenFolder(path); }); + // If we have written files, open explorer and select them grouped by folder; otherwise fall back to opening containing folder. + if (writtenFiles.Count > 0) + { + output.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolderAndSelectItems(writtenFiles); }); + } + else + { + if (isFile && File.Exists(path)) + output.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolderAndSelectItems(new[] { path }); }); + else + output.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolder(path); }); + } output.WriteLine(); return output; }, ct)).Then(dockWorkspace.ShowText).HandleExceptions(); diff --git a/ILSpy/TreeNodes/AssemblyTreeNode.cs b/ILSpy/TreeNodes/AssemblyTreeNode.cs index 194c15ce1..652a23024 100644 --- a/ILSpy/TreeNodes/AssemblyTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyTreeNode.cs @@ -690,15 +690,18 @@ namespace ICSharpCode.ILSpy.TreeNodes { if (context.SelectedTreeNodes == null) return; + var paths = new List(); foreach (var n in context.SelectedTreeNodes) { var node = GetAssemblyTreeNode(n); var path = node.LoadedAssembly.FileName; if (File.Exists(path)) { - ShellHelper.OpenFolderAndSelectItem(path); + paths.Add(path); } } + if (paths.Count > 0) + ShellHelper.OpenFolderAndSelectItems(paths); } }