diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index 380dbbe6c6..cd3c692291 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -4452,6 +4452,10 @@ Activate by holding the key for the character you want to add an accent to, then Hide the built-in "New" context menu Localize New in accordance with Windows New + + Couldn't update the built-in "New" context menu setting. + User-facing error shown when New+ fails to update the built-in New registry setting + Behavior New+ behavior related settings label diff --git a/src/settings-ui/Settings.UI/ViewModels/NewPlusViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/NewPlusViewModel.cs index b34d5c600c..f0e0adca09 100644 --- a/src/settings-ui/Settings.UI/ViewModels/NewPlusViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/NewPlusViewModel.cs @@ -12,6 +12,7 @@ using System.Windows; using global::PowerToys.GPOWrapper; using ManagedCommon; +using Microsoft.PowerToys.Settings.UI.Helpers; using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; @@ -124,7 +125,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels // Re-enable built-in New handler when NewPlus is disabled if allowed by GPO if (!IsNewPlusHideBuiltInNewToggleSettingGPOConfigured) { - EnableBuiltInNewViaRegistry(); + if (EnableBuiltInNewViaRegistry()) + { + UpdateHideBuiltInNewState(false); + } } } } @@ -253,22 +257,15 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels if (_disableBuiltInNew != value) { // Update New visibility right now - if (_disableBuiltInNew) + bool registryUpdateSucceeded = value ? DisableBuiltInNewViaRegistry() : EnableBuiltInNewViaRegistry(); + + if (!registryUpdateSucceeded) { - EnableBuiltInNewViaRegistry(); - } - else - { - DisableBuiltInNewViaRegistry(); + OnPropertyChanged(nameof(HideBuiltInNew)); + return; } - _disableBuiltInNew = value; - OnPropertyChanged(nameof(HideBuiltInNew)); - - // Set the user preference for New visibility, which we then also use in powertoys_module.cpp to ensure - // that backup/restore of settings work without having to update settings - Settings.Properties.BuiltInNewHidePreference.Value = value; - NotifySettingsChanged(); + UpdateHideBuiltInNewState(value); } } } @@ -393,6 +390,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels { using (var newKey = Registry.CurrentUser.OpenSubKey(BuiltInNewRegistryPath, writable: false)) { + if (newKey is null) + { + // Missing key means Explorer is using the built-in handler state, which is enabled. + return true; + } + string builtInNewHandlerValue = newKey.GetValue(null, null) as string; if (builtInNewHandlerValue is null || string.Equals(builtInNewHandlerValue, BuiltNewCOMGuid, StringComparison.OrdinalIgnoreCase)) @@ -412,18 +415,34 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels return false; } - private void DisableBuiltInNewViaRegistry() + private void UpdateHideBuiltInNewState(bool hideBuiltInNew) + { + _disableBuiltInNew = hideBuiltInNew; + OnPropertyChanged(nameof(HideBuiltInNew)); + + // Set the user preference for New visibility, which we then also use in powertoys_module.cpp to ensure + // that backup/restore of settings work without having to update settings + Settings.Properties.BuiltInNewHidePreference.Value = hideBuiltInNew; + NotifySettingsChanged(); + } + + private bool DisableBuiltInNewViaRegistry() { try { - using (var newKey = Registry.CurrentUser.OpenSubKey(BuiltInNewRegistryPath, writable: true)) + using (var newKey = Registry.CurrentUser.CreateSubKey(BuiltInNewRegistryPath, writable: true)) { + if (newKey is null) + { + throw new InvalidOperationException("Failed to open or create the registry key for built-in New."); + } + string builtInNewHandlerValue = newKey.GetValue(null, null) as string; if (!string.IsNullOrEmpty(builtInNewHandlerValue) && builtInNewHandlerValue.StartsWith(NewDisabledValuePrefix, StringComparison.OrdinalIgnoreCase)) { // Already disabled - return; + return true; } // Any string value will disable the built-in New handler @@ -431,42 +450,50 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels newKey.SetValue(string.Empty, newDisabledValue); } - HideBuiltInNew = true; - OnPropertyChanged(nameof(HideBuiltInNew)); + return true; } catch (Exception ex) { Logger.LogError("Failed to disable built-in New in the registry.", ex); - MessageBox.Show(ex.Message); + MessageBox.Show(ResourceLoaderInstance.ResourceLoader.GetString("NewPlus_BuiltInNewRegistryUpdateError")); } + + return false; } - private void EnableBuiltInNewViaRegistry() + private bool EnableBuiltInNewViaRegistry() { try { using (var newKey = Registry.CurrentUser.OpenSubKey(BuiltInNewRegistryPath, writable: true)) { + if (newKey is null) + { + // Missing key means the built-in New handler is already enabled. + return true; + } + string builtInNewHandlerValue = newKey.GetValue(null, null) as string; if (builtInNewHandlerValue is null) { // Already enabled - return; + return true; } // Null key default value enables built-in New handler newKey.DeleteValue(null, true); } - HideBuiltInNew = false; - OnPropertyChanged(nameof(HideBuiltInNew)); + return true; } catch (Exception ex) { Logger.LogError("Failed to enable built-in New in the registry.", ex); - MessageBox.Show(ex.Message); + MessageBox.Show(ResourceLoaderInstance.ResourceLoader.GetString("NewPlus_BuiltInNewRegistryUpdateError")); } + + return false; } } }