From be7ade09e85bee32e6435571f99c8e8e2fc04608 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 15 May 2026 08:20:53 +0200 Subject: [PATCH] =?UTF-8?q?Open=20from=20GAC=20dialog=20=E2=80=94=20Window?= =?UTF-8?q?s-only,=20mirrors=20WPF=20gating?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the NotImplementedDialog stub in OpenFromGacCommand with a real dialog. CanExecute gates on OperatingSystem.IsWindows() since the Windows Global Assembly Cache doesn't exist on Linux/macOS (matches WPF's AppEnvironment.IsWindows gate). The actual GAC enumeration uses the shared UniversalAssemblyResolver.EnumerateGac() + GetAssemblyInGac() pair from ICSharpCode.Decompiler — no platform-specific code in the Avalonia tree. Assisted-by: Claude:claude-opus-4-7:Claude Code --- ILSpy/Commands/FileCommands.cs | 34 +++++- ILSpy/Views/OpenFromGacDialog.axaml | 25 +++++ ILSpy/Views/OpenFromGacDialog.axaml.cs | 149 +++++++++++++++++++++++++ 3 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 ILSpy/Views/OpenFromGacDialog.axaml create mode 100644 ILSpy/Views/OpenFromGacDialog.axaml.cs diff --git a/ILSpy/Commands/FileCommands.cs b/ILSpy/Commands/FileCommands.cs index f683dcf6c..92a15da59 100644 --- a/ILSpy/Commands/FileCommands.cs +++ b/ILSpy/Commands/FileCommands.cs @@ -89,7 +89,39 @@ namespace ILSpy.Commands [Shared] sealed class OpenFromGacCommand : SimpleCommand { - public override void Execute(object? parameter) => NotImplementedDialog.Show(Resources.OpenFrom_GAC); + readonly AssemblyTreeModel assemblyTreeModel; + + [ImportingConstructor] + public OpenFromGacCommand(AssemblyTreeModel assemblyTreeModel) + { + this.assemblyTreeModel = assemblyTreeModel; + } + + // The Windows GAC doesn't exist on Linux/macOS. WPF gates this command on + // `AppEnvironment.IsWindows`; Avalonia uses the BCL runtime check that already + // returns the right answer per OS. + public override bool CanExecute(object? parameter) => System.OperatingSystem.IsWindows(); + + public override void Execute(object? parameter) + { + if (!CanExecute(parameter)) + return; + var owner = (global::Avalonia.Application.Current?.ApplicationLifetime + as global::Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime)?.MainWindow; + if (owner == null) + return; + _ = ShowAsync(owner); + } + + async System.Threading.Tasks.Task ShowAsync(global::Avalonia.Controls.Window owner) + { + var dlg = new Views.OpenFromGacDialog(); + var fileNames = await dlg.ShowDialog(owner); + if (fileNames == null || fileNames.Length == 0) + return; + foreach (var name in fileNames) + assemblyTreeModel.AssemblyList?.OpenAssembly(name); + } } [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.ManageAssembly_Lists), MenuIcon = "Images/AssemblyList", MenuCategory = nameof(Resources.Open), MenuOrder = 1.7)] diff --git a/ILSpy/Views/OpenFromGacDialog.axaml b/ILSpy/Views/OpenFromGacDialog.axaml new file mode 100644 index 000000000..0687c75d9 --- /dev/null +++ b/ILSpy/Views/OpenFromGacDialog.axaml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + +