mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-26 18:58:29 +08:00
ee904ae1b1
* Merge and conflict resolution * Messages good, backup/restore algo better. * Start of "GetExportVerion" * fixed spelling * New backup/restore mode working. * Rename a project * Removed test project * Switch to text.json * Renamed BackupAndSync to BackupAndRestore * Added IgnoredPTRunSettings and full merge * Restored "fixed" settings that change for no reason * Various UI updates. * speling * Some cleanup and zip support. * Merge and clean * code clean up * code clean up * code clean up * Smarter settings compare and merge. * config based file include/exclude * Removed some "words" * Code clean up * cleanup * cleanup * cleanup * cleanup * fixed spelling. * Fixed clean up 1 * more clean up * Trying to add ptb as an OK word * Some UI updates. * UI tweaks and PR review items. * UI tweaks * Merge conflicts resolved. * Added CurrentSettingMatchText * PR review updates. * Removed weird file. * Review updates and fixes * More UI tweaks. * UI tweaks * Set default backup location to "%USERPROFILE%\\Documents\\PowerToys\\Backup" * settings ui tweaks * Added ExpanderContentSettingStyle * fix missing config file * fix missing config file, part 2 * update ui, cleanup cope * update ui, cleanup code - Part2 * update method comments * code cleanup and adjust Backup message time * fix changing backup location on empty Regsitry * fix select location - part 2 * location input box min-width * remove lastRestoreDate from ViewModel * Code or backup timing, and error handling. * Should fix file/folder name crash. * Progress to instance class for backup/restore * Persist backup status state, added refresh button. * Better auto check for settings status * Some UI/text updates. * Clean up * Added prefix for "General_Settings" to resources * Code review updates. * Code review changes. * Changed to FolderPicker per review * Fixed issue with early delete of cleanup. * Testing issues with FolderPicker * Removed WinForm req and fixed win10 issue. * Review update. * Review changes. Co-authored-by: htcfreek <61519853+htcfreek@users.noreply.github.com>
169 lines
7.5 KiB
C#
169 lines
7.5 KiB
C#
// Copyright (c) Microsoft Corporation
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.IO.Abstractions;
|
|
using System.Text.Json;
|
|
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
|
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
|
|
|
|
namespace Microsoft.PowerToys.Settings.UI.Library
|
|
{
|
|
public class SettingsUtils : ISettingsUtils
|
|
{
|
|
private const string DefaultFileName = "settings.json";
|
|
private const string DefaultModuleName = "";
|
|
private readonly IFile _file;
|
|
private readonly ISettingsPath _settingsPath;
|
|
|
|
public SettingsUtils()
|
|
: this(new FileSystem())
|
|
{
|
|
}
|
|
|
|
public SettingsUtils(IFileSystem fileSystem)
|
|
: this(fileSystem?.File, new SettingPath(fileSystem?.Directory, fileSystem?.Path))
|
|
{
|
|
}
|
|
|
|
public SettingsUtils(IFile file, ISettingsPath settingPath)
|
|
{
|
|
_file = file ?? throw new ArgumentNullException(nameof(file));
|
|
_settingsPath = settingPath;
|
|
}
|
|
|
|
public bool SettingsExists(string powertoy = DefaultModuleName, string fileName = DefaultFileName)
|
|
{
|
|
var settingsPath = _settingsPath.GetSettingsPath(powertoy, fileName);
|
|
return _file.Exists(settingsPath);
|
|
}
|
|
|
|
public void DeleteSettings(string powertoy = "")
|
|
{
|
|
_settingsPath.DeleteSettings(powertoy);
|
|
}
|
|
|
|
public T GetSettings<T>(string powertoy = DefaultModuleName, string fileName = DefaultFileName)
|
|
where T : ISettingsConfig, new()
|
|
{
|
|
if (!SettingsExists(powertoy, fileName))
|
|
{
|
|
throw new FileNotFoundException();
|
|
}
|
|
|
|
// Given the file already exists, to deserialize the file and read its content.
|
|
T deserializedSettings = GetFile<T>(powertoy, fileName);
|
|
|
|
// If the file needs to be modified, to save the new configurations accordingly.
|
|
if (deserializedSettings.UpgradeSettingsConfiguration())
|
|
{
|
|
SaveSettings(deserializedSettings.ToJsonString(), powertoy, fileName);
|
|
}
|
|
|
|
return deserializedSettings;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a Deserialized object of the json settings string.
|
|
/// This function creates a file in the powertoy folder if it does not exist and returns an object with default properties.
|
|
/// </summary>
|
|
/// <returns>Deserialized json settings object.</returns>
|
|
public T GetSettingsOrDefault<T>(string powertoy = DefaultModuleName, string fileName = DefaultFileName)
|
|
where T : ISettingsConfig, new()
|
|
{
|
|
try
|
|
{
|
|
return GetSettings<T>(powertoy, fileName);
|
|
}
|
|
|
|
// Catch json deserialization exceptions when the file is corrupt and has an invalid json.
|
|
// If there are any deserialization issues like in https://github.com/microsoft/PowerToys/issues/7500, log the error and create a new settings.json file.
|
|
// This is different from the case where we have trailing zeros following a valid json file, which we have handled by trimming the trailing zeros.
|
|
catch (JsonException ex)
|
|
{
|
|
Logger.LogError($"Exception encountered while loading {powertoy} settings.", ex);
|
|
}
|
|
catch (FileNotFoundException)
|
|
{
|
|
Logger.LogInfo($"Settings file {fileName} for {powertoy} was not found.");
|
|
}
|
|
|
|
// If the settings file does not exist or if the file is corrupt, to create a new object with default parameters and save it to a newly created settings file.
|
|
T newSettingsItem = new T();
|
|
SaveSettings(newSettingsItem.ToJsonString(), powertoy, fileName);
|
|
return newSettingsItem;
|
|
}
|
|
|
|
// Given the powerToy folder name and filename to be accessed, this function deserializes and returns the file.
|
|
private T GetFile<T>(string powertoyFolderName = DefaultModuleName, string fileName = DefaultFileName)
|
|
{
|
|
// Adding Trim('\0') to overcome possible NTFS file corruption.
|
|
// Look at issue https://github.com/microsoft/PowerToys/issues/6413 you'll see the file has a large sum of \0 to fill up a 4096 byte buffer for writing to disk
|
|
// This, while not totally ideal, does work around the problem by trimming the end.
|
|
// The file itself did write the content correctly but something is off with the actual end of the file, hence the 0x00 bug
|
|
var jsonSettingsString = _file.ReadAllText(_settingsPath.GetSettingsPath(powertoyFolderName, fileName)).Trim('\0');
|
|
return JsonSerializer.Deserialize<T>(jsonSettingsString);
|
|
}
|
|
|
|
// Save settings to a json file.
|
|
public void SaveSettings(string jsonSettings, string powertoy = DefaultModuleName, string fileName = DefaultFileName)
|
|
{
|
|
try
|
|
{
|
|
if (jsonSettings != null)
|
|
{
|
|
if (!_settingsPath.SettingsFolderExists(powertoy))
|
|
{
|
|
_settingsPath.CreateSettingsFolder(powertoy);
|
|
}
|
|
|
|
_file.WriteAllText(_settingsPath.GetSettingsPath(powertoy, fileName), jsonSettings);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.LogError($"Exception encountered while saving {powertoy} settings.", e);
|
|
#if DEBUG
|
|
if (e is ArgumentException || e is ArgumentNullException || e is PathTooLongException)
|
|
{
|
|
throw;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// Returns the file path to the settings file, that is exposed from the local ISettingsPath instance.
|
|
public string GetSettingsFilePath(string powertoy = "", string fileName = "settings.json")
|
|
{
|
|
return _settingsPath.GetSettingsPath(powertoy, fileName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method <c>BackupSettings</c> Mostly a wrapper for SettingsBackupAndRestoreUtils.BackupSettings
|
|
/// </summary>
|
|
public static (bool success, string message, string severity, bool lastBackupExists) BackupSettings()
|
|
{
|
|
var settingsBackupAndRestoreUtilsX = SettingsBackupAndRestoreUtils.Instance;
|
|
var settingsUtils = new SettingsUtils();
|
|
var appBasePath = Path.GetDirectoryName(settingsUtils._settingsPath.GetSettingsPath(string.Empty, string.Empty));
|
|
string settingsBackupAndRestoreDir = settingsBackupAndRestoreUtilsX.GetSettingsBackupAndRestoreDir();
|
|
|
|
return settingsBackupAndRestoreUtilsX.BackupSettings(appBasePath, settingsBackupAndRestoreDir, false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method <c>RestoreSettings</c> Mostly a wrapper for SettingsBackupAndRestoreUtils.RestoreSettings
|
|
/// </summary>
|
|
public static (bool success, string message, string severity) RestoreSettings()
|
|
{
|
|
var settingsBackupAndRestoreUtilsX = SettingsBackupAndRestoreUtils.Instance;
|
|
var settingsUtils = new SettingsUtils();
|
|
var appBasePath = Path.GetDirectoryName(settingsUtils._settingsPath.GetSettingsPath(string.Empty, string.Empty));
|
|
string settingsBackupAndRestoreDir = settingsBackupAndRestoreUtilsX.GetSettingsBackupAndRestoreDir();
|
|
return settingsBackupAndRestoreUtilsX.RestoreSettings(appBasePath, settingsBackupAndRestoreDir);
|
|
}
|
|
}
|
|
}
|