From 6ca2cd667bdf269a42fd8de13f97865821ad9291 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 23 Dec 2025 23:48:22 +0000
Subject: [PATCH 1/8] Initial plan
From 25d20737190ffc3901c378d1890c2e79a83f24fc Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 23 Dec 2025 23:52:38 +0000
Subject: [PATCH 2/8] Migrate SettingsManager to use JSON format with automatic
XML migration
Co-authored-by: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com>
---
.../NETworkManager.Settings/SettingsInfo.cs | 4 +-
.../SettingsManager.cs | 83 +++++++++++++++++--
2 files changed, 79 insertions(+), 8 deletions(-)
diff --git a/Source/NETworkManager.Settings/SettingsInfo.cs b/Source/NETworkManager.Settings/SettingsInfo.cs
index 7f195085d2..d3d5d4c83f 100644
--- a/Source/NETworkManager.Settings/SettingsInfo.cs
+++ b/Source/NETworkManager.Settings/SettingsInfo.cs
@@ -13,7 +13,7 @@
using System.Collections.Specialized;
using System.ComponentModel;
using System.Runtime.CompilerServices;
-using System.Xml.Serialization;
+using System.Text.Json.Serialization;
// ReSharper disable InconsistentNaming
@@ -42,7 +42,7 @@ private void OnPropertyChanged([CallerMemberName] string propertyName = null)
#region Variables
- [XmlIgnore] public bool SettingsChanged { get; set; }
+ [JsonIgnore] public bool SettingsChanged { get; set; }
///
/// Private field for the property.
diff --git a/Source/NETworkManager.Settings/SettingsManager.cs b/Source/NETworkManager.Settings/SettingsManager.cs
index cbd20d5ff4..678e9ac7a4 100644
--- a/Source/NETworkManager.Settings/SettingsManager.cs
+++ b/Source/NETworkManager.Settings/SettingsManager.cs
@@ -4,6 +4,8 @@
using System;
using System.IO;
using System.Linq;
+using System.Text.Json;
+using System.Text.Json.Serialization;
using System.Xml.Serialization;
namespace NETworkManager.Settings;
@@ -30,7 +32,12 @@ public static class SettingsManager
///
/// Settings file extension.
///
- private static string SettingsFileExtension => ".xml";
+ private static string SettingsFileExtension => ".json";
+
+ ///
+ /// Legacy XML settings file extension.
+ ///
+ private static string LegacySettingsFileExtension => ".xml";
///
/// Settings that are currently loaded.
@@ -76,6 +83,15 @@ public static string GetSettingsFilePath()
return Path.Combine(GetSettingsFolderLocation(), GetSettingsFileName());
}
+ ///
+ /// Method to get the legacy XML settings file path.
+ ///
+ /// Legacy XML settings file path.
+ private static string GetLegacySettingsFilePath()
+ {
+ return Path.Combine(GetSettingsFolderLocation(), $"{SettingsFileName}{LegacySettingsFileExtension}");
+ }
+
#endregion
#region Initialize, load and save
@@ -99,7 +115,9 @@ public static void Initialize()
public static void Load()
{
var filePath = GetSettingsFilePath();
+ var legacyFilePath = GetLegacySettingsFilePath();
+ // Check if JSON file exists
if (File.Exists(filePath))
{
Current = DeserializeFromFile(filePath);
@@ -109,16 +127,64 @@ public static void Load()
return;
}
+ // Check if legacy XML file exists and migrate it
+ if (File.Exists(legacyFilePath))
+ {
+ Log.Info("Legacy XML settings file found. Migrating to JSON format...");
+
+ Current = DeserializeFromXmlFile(legacyFilePath);
+
+ Current.SettingsChanged = false;
+
+ // Save in new JSON format
+ Save();
+
+ // Backup the old XML file
+ var backupFilePath = Path.Combine(GetSettingsFolderLocation(),
+ $"{SettingsFileName}{LegacySettingsFileExtension}.backup");
+ File.Copy(legacyFilePath, backupFilePath, true);
+ Log.Info($"Legacy XML settings file backed up to: {backupFilePath}");
+
+ // Optionally, delete the original XML file after successful migration
+ // File.Delete(legacyFilePath);
+
+ Log.Info("Settings migration from XML to JSON completed successfully.");
+
+ return;
+ }
+
// Initialize the default settings if there is no settings file.
Initialize();
}
///
- /// Method to deserialize the settings from a file.
+ /// Method to deserialize the settings from a JSON file.
///
/// Path to the settings file.
/// Settings as .
private static SettingsInfo DeserializeFromFile(string filePath)
+ {
+ var jsonString = File.ReadAllText(filePath);
+
+ var options = new JsonSerializerOptions
+ {
+ WriteIndented = true,
+ PropertyNameCaseInsensitive = true,
+ DefaultIgnoreCondition = JsonIgnoreCondition.Never,
+ Converters = { new JsonStringEnumConverter() }
+ };
+
+ var settingsInfo = JsonSerializer.Deserialize(jsonString, options);
+
+ return settingsInfo;
+ }
+
+ ///
+ /// Method to deserialize the settings from a legacy XML file.
+ ///
+ /// Path to the XML settings file.
+ /// Settings as .
+ private static SettingsInfo DeserializeFromXmlFile(string filePath)
{
var xmlSerializer = new XmlSerializer(typeof(SettingsInfo));
@@ -145,16 +211,21 @@ public static void Save()
}
///
- /// Method to serialize the settings to a file.
+ /// Method to serialize the settings to a JSON file.
///
/// Path to the settings file.
private static void SerializeToFile(string filePath)
{
- var xmlSerializer = new XmlSerializer(typeof(SettingsInfo));
+ var options = new JsonSerializerOptions
+ {
+ WriteIndented = true,
+ DefaultIgnoreCondition = JsonIgnoreCondition.Never,
+ Converters = { new JsonStringEnumConverter() }
+ };
- using var fileStream = new FileStream(filePath, FileMode.Create);
+ var jsonString = JsonSerializer.Serialize(Current, options);
- xmlSerializer.Serialize(fileStream, Current);
+ File.WriteAllText(filePath, jsonString);
}
#endregion
From 68874f22a81f7efa289c858a44a6c119c1d7d3e1 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 23 Dec 2025 23:55:27 +0000
Subject: [PATCH 3/8] Add JSON exception handling in App.xaml.cs
Co-authored-by: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com>
---
Source/NETworkManager/App.xaml.cs | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/Source/NETworkManager/App.xaml.cs b/Source/NETworkManager/App.xaml.cs
index 249efe1a39..611d0a3f19 100644
--- a/Source/NETworkManager/App.xaml.cs
+++ b/Source/NETworkManager/App.xaml.cs
@@ -2,6 +2,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
+using System.Text.Json;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
@@ -108,6 +109,24 @@ by BornToBeRoot
SettingsManager.Initialize();
ConfigurationManager.Current.ShowSettingsResetNoteOnStartup = true;
}
+ catch (JsonException ex)
+ {
+ Log.Error("Could not load application settings! JSON file is corrupted or invalid.");
+ Log.Error(ex.Message + "-" + ex.StackTrace);
+
+ // Create backup of corrupted file
+ var destinationFile =
+ $"{TimestampHelper.GetTimestamp()}_corrupted_" + SettingsManager.GetSettingsFileName();
+ File.Copy(SettingsManager.GetSettingsFilePath(),
+ Path.Combine(SettingsManager.GetSettingsFolderLocation(), destinationFile));
+ Log.Info($"A backup of the corrupted settings file has been saved under {destinationFile}");
+
+ // Initialize default application settings
+ Log.Info("Initialize default application settings...");
+
+ SettingsManager.Initialize();
+ ConfigurationManager.Current.ShowSettingsResetNoteOnStartup = true;
+ }
// Upgrade settings if necessary
var settingsVersion = Version.Parse(SettingsManager.Current.Version);
From 47faca2d42d54d7e70a2293fd24c4bf1c072ca72 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 23 Dec 2025 23:57:19 +0000
Subject: [PATCH 4/8] Address code review comments: refactor JSON options and
add null check
Co-authored-by: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com>
---
.../SettingsManager.cs | 37 ++++++++++---------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/Source/NETworkManager.Settings/SettingsManager.cs b/Source/NETworkManager.Settings/SettingsManager.cs
index 678e9ac7a4..c6634abf14 100644
--- a/Source/NETworkManager.Settings/SettingsManager.cs
+++ b/Source/NETworkManager.Settings/SettingsManager.cs
@@ -49,6 +49,17 @@ public static class SettingsManager
///
public static bool HotKeysChanged { get; set; }
+ ///
+ /// JSON serializer options for consistent serialization/deserialization.
+ ///
+ private static readonly JsonSerializerOptions JsonOptions = new()
+ {
+ WriteIndented = true,
+ PropertyNameCaseInsensitive = true,
+ DefaultIgnoreCondition = JsonIgnoreCondition.Never,
+ Converters = { new JsonStringEnumConverter() }
+ };
+
#endregion
#region Settings location, default paths and file names
@@ -145,8 +156,8 @@ public static void Load()
File.Copy(legacyFilePath, backupFilePath, true);
Log.Info($"Legacy XML settings file backed up to: {backupFilePath}");
- // Optionally, delete the original XML file after successful migration
- // File.Delete(legacyFilePath);
+ // Note: The original XML file is intentionally not deleted to allow users to revert if needed.
+ // Users can manually delete Settings.xml after verifying the migration was successful.
Log.Info("Settings migration from XML to JSON completed successfully.");
@@ -166,15 +177,12 @@ private static SettingsInfo DeserializeFromFile(string filePath)
{
var jsonString = File.ReadAllText(filePath);
- var options = new JsonSerializerOptions
- {
- WriteIndented = true,
- PropertyNameCaseInsensitive = true,
- DefaultIgnoreCondition = JsonIgnoreCondition.Never,
- Converters = { new JsonStringEnumConverter() }
- };
+ var settingsInfo = JsonSerializer.Deserialize(jsonString, JsonOptions);
- var settingsInfo = JsonSerializer.Deserialize(jsonString, options);
+ if (settingsInfo == null)
+ {
+ throw new InvalidOperationException("Failed to deserialize settings from JSON file. The result was null.");
+ }
return settingsInfo;
}
@@ -216,14 +224,7 @@ public static void Save()
/// Path to the settings file.
private static void SerializeToFile(string filePath)
{
- var options = new JsonSerializerOptions
- {
- WriteIndented = true,
- DefaultIgnoreCondition = JsonIgnoreCondition.Never,
- Converters = { new JsonStringEnumConverter() }
- };
-
- var jsonString = JsonSerializer.Serialize(Current, options);
+ var jsonString = JsonSerializer.Serialize(Current, JsonOptions);
File.WriteAllText(filePath, jsonString);
}
From a1037c361ae50254de37273d1c500aff2016e21d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 24 Dec 2025 00:00:14 +0000
Subject: [PATCH 5/8] Fix remaining code review issues: extract common error
handling, add null checks, use timestamped backups
Co-authored-by: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com>
---
.../SettingsManager.cs | 14 ++++--
Source/NETworkManager/App.xaml.cs | 45 +++++++++----------
2 files changed, 31 insertions(+), 28 deletions(-)
diff --git a/Source/NETworkManager.Settings/SettingsManager.cs b/Source/NETworkManager.Settings/SettingsManager.cs
index c6634abf14..6e3cd571f7 100644
--- a/Source/NETworkManager.Settings/SettingsManager.cs
+++ b/Source/NETworkManager.Settings/SettingsManager.cs
@@ -1,6 +1,7 @@
using log4net;
using NETworkManager.Models;
using NETworkManager.Models.Network;
+using NETworkManager.Utilities;
using System;
using System.IO;
using System.Linq;
@@ -150,10 +151,10 @@ public static void Load()
// Save in new JSON format
Save();
- // Backup the old XML file
+ // Backup the old XML file with timestamp to avoid overwriting existing backups
var backupFilePath = Path.Combine(GetSettingsFolderLocation(),
- $"{SettingsFileName}{LegacySettingsFileExtension}.backup");
- File.Copy(legacyFilePath, backupFilePath, true);
+ $"{SettingsFileName}_{TimestampHelper.GetTimestamp()}{LegacySettingsFileExtension}.backup");
+ File.Copy(legacyFilePath, backupFilePath, false);
Log.Info($"Legacy XML settings file backed up to: {backupFilePath}");
// Note: The original XML file is intentionally not deleted to allow users to revert if needed.
@@ -198,7 +199,12 @@ private static SettingsInfo DeserializeFromXmlFile(string filePath)
using var fileStream = new FileStream(filePath, FileMode.Open);
- var settingsInfo = (SettingsInfo)xmlSerializer.Deserialize(fileStream);
+ var settingsInfo = xmlSerializer.Deserialize(fileStream) as SettingsInfo;
+
+ if (settingsInfo == null)
+ {
+ throw new InvalidOperationException("Failed to deserialize settings from XML file. The result was null.");
+ }
return settingsInfo;
}
diff --git a/Source/NETworkManager/App.xaml.cs b/Source/NETworkManager/App.xaml.cs
index 611d0a3f19..b1d067e00e 100644
--- a/Source/NETworkManager/App.xaml.cs
+++ b/Source/NETworkManager/App.xaml.cs
@@ -96,36 +96,14 @@ by BornToBeRoot
Log.Error("Could not load application settings!");
Log.Error(ex.Message + "-" + ex.StackTrace);
- // Create backup of corrupted file
- var destinationFile =
- $"{TimestampHelper.GetTimestamp()}_corrupted_" + SettingsManager.GetSettingsFileName();
- File.Copy(SettingsManager.GetSettingsFilePath(),
- Path.Combine(SettingsManager.GetSettingsFolderLocation(), destinationFile));
- Log.Info($"A backup of the corrupted settings file has been saved under {destinationFile}");
-
- // Initialize default application settings
- Log.Info("Initialize default application settings...");
-
- SettingsManager.Initialize();
- ConfigurationManager.Current.ShowSettingsResetNoteOnStartup = true;
+ HandleCorruptedSettingsFile();
}
catch (JsonException ex)
{
Log.Error("Could not load application settings! JSON file is corrupted or invalid.");
Log.Error(ex.Message + "-" + ex.StackTrace);
- // Create backup of corrupted file
- var destinationFile =
- $"{TimestampHelper.GetTimestamp()}_corrupted_" + SettingsManager.GetSettingsFileName();
- File.Copy(SettingsManager.GetSettingsFilePath(),
- Path.Combine(SettingsManager.GetSettingsFolderLocation(), destinationFile));
- Log.Info($"A backup of the corrupted settings file has been saved under {destinationFile}");
-
- // Initialize default application settings
- Log.Info("Initialize default application settings...");
-
- SettingsManager.Initialize();
- ConfigurationManager.Current.ShowSettingsResetNoteOnStartup = true;
+ HandleCorruptedSettingsFile();
}
// Upgrade settings if necessary
@@ -239,6 +217,25 @@ by BornToBeRoot
}
}
+ ///
+ /// Handles a corrupted settings file by creating a backup and initializing default settings.
+ ///
+ private void HandleCorruptedSettingsFile()
+ {
+ // Create backup of corrupted file
+ var destinationFile =
+ $"{TimestampHelper.GetTimestamp()}_corrupted_" + SettingsManager.GetSettingsFileName();
+ File.Copy(SettingsManager.GetSettingsFilePath(),
+ Path.Combine(SettingsManager.GetSettingsFolderLocation(), destinationFile));
+ Log.Info($"A backup of the corrupted settings file has been saved under {destinationFile}");
+
+ // Initialize default application settings
+ Log.Info("Initialize default application settings...");
+
+ SettingsManager.Initialize();
+ ConfigurationManager.Current.ShowSettingsResetNoteOnStartup = true;
+ }
+
private void DispatcherTimer_Tick(object sender, EventArgs e)
{
Log.Info("Run background job...");
From 03be70beea8f8ea9b983731b379fe14bac9b8fb5 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 24 Dec 2025 00:01:53 +0000
Subject: [PATCH 6/8] Fix backup file copy to allow overwrite for
same-timestamp scenarios
Co-authored-by: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com>
---
Source/NETworkManager.Settings/SettingsManager.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Source/NETworkManager.Settings/SettingsManager.cs b/Source/NETworkManager.Settings/SettingsManager.cs
index 6e3cd571f7..12fb6703b5 100644
--- a/Source/NETworkManager.Settings/SettingsManager.cs
+++ b/Source/NETworkManager.Settings/SettingsManager.cs
@@ -152,9 +152,11 @@ public static void Load()
Save();
// Backup the old XML file with timestamp to avoid overwriting existing backups
+ // If a backup with the same timestamp exists (unlikely), it will be overwritten
+ // since it represents the same migration attempt
var backupFilePath = Path.Combine(GetSettingsFolderLocation(),
$"{SettingsFileName}_{TimestampHelper.GetTimestamp()}{LegacySettingsFileExtension}.backup");
- File.Copy(legacyFilePath, backupFilePath, false);
+ File.Copy(legacyFilePath, backupFilePath, true);
Log.Info($"Legacy XML settings file backed up to: {backupFilePath}");
// Note: The original XML file is intentionally not deleted to allow users to revert if needed.
From 68522663efa77d62fd4eecf9ef5b537119db9dd8 Mon Sep 17 00:00:00 2001
From: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com>
Date: Wed, 24 Dec 2025 17:06:58 +0100
Subject: [PATCH 7/8] Feature: Migrate settings to json
---
.../SettingsManager.cs | 69 ++++++++++++++-----
Source/NETworkManager/App.xaml.cs | 12 ++--
2 files changed, 56 insertions(+), 25 deletions(-)
diff --git a/Source/NETworkManager.Settings/SettingsManager.cs b/Source/NETworkManager.Settings/SettingsManager.cs
index 12fb6703b5..1ce2e093d4 100644
--- a/Source/NETworkManager.Settings/SettingsManager.cs
+++ b/Source/NETworkManager.Settings/SettingsManager.cs
@@ -25,6 +25,11 @@ public static class SettingsManager
///
private static string SettingsFolderName => "Settings";
+ ///
+ /// Settings backups directory name.
+ ///
+ private static string BackupFolderName => "Backups";
+
///
/// Settings file name.
///
@@ -38,6 +43,7 @@ public static class SettingsManager
///
/// Legacy XML settings file extension.
///
+ [Obsolete("Legacy XML settings are no longer used, but the extension is kept for migration purposes.")]
private static string LegacySettingsFileExtension => ".xml";
///
@@ -77,6 +83,15 @@ public static string GetSettingsFolderLocation()
AssemblyManager.Current.Name, SettingsFolderName);
}
+ ///
+ /// Method to get the path of the settings backup folder.
+ ///
+ /// Path to the settings backup folder.
+ public static string GetSettingsBackupFolderLocation()
+ {
+ return Path.Combine(GetSettingsFolderLocation(), BackupFolderName);
+ }
+
///
/// Method to get the settings file name.
///
@@ -86,6 +101,16 @@ public static string GetSettingsFileName()
return $"{SettingsFileName}{SettingsFileExtension}";
}
+ ///
+ /// Method to get the legacy settings file name.
+ ///
+ /// Legacy settings file name.
+ [Obsolete("Legacy XML settings are no longer used, but the method is kept for migration purposes.")]
+ public static string GetLegacySettingsFileName()
+ {
+ return $"{SettingsFileName}{LegacySettingsFileExtension}";
+ }
+
///
/// Method to get the settings file path.
///
@@ -99,9 +124,10 @@ public static string GetSettingsFilePath()
/// Method to get the legacy XML settings file path.
///
/// Legacy XML settings file path.
+ [Obsolete("Legacy XML settings are no longer used, but the method is kept for migration purposes.")]
private static string GetLegacySettingsFilePath()
{
- return Path.Combine(GetSettingsFolderLocation(), $"{SettingsFileName}{LegacySettingsFileExtension}");
+ return Path.Combine(GetSettingsFolderLocation(), GetLegacySettingsFileName());
}
#endregion
@@ -151,16 +177,17 @@ public static void Load()
// Save in new JSON format
Save();
- // Backup the old XML file with timestamp to avoid overwriting existing backups
- // If a backup with the same timestamp exists (unlikely), it will be overwritten
- // since it represents the same migration attempt
- var backupFilePath = Path.Combine(GetSettingsFolderLocation(),
- $"{SettingsFileName}_{TimestampHelper.GetTimestamp()}{LegacySettingsFileExtension}.backup");
+ // Create a backup of the legacy XML file and delete the original
+ Directory.CreateDirectory(GetSettingsBackupFolderLocation());
+
+ var backupFilePath = Path.Combine(GetSettingsBackupFolderLocation(),
+ $"{TimestampHelper.GetTimestamp()}_{GetLegacySettingsFileName()}");
+
File.Copy(legacyFilePath, backupFilePath, true);
- Log.Info($"Legacy XML settings file backed up to: {backupFilePath}");
- // Note: The original XML file is intentionally not deleted to allow users to revert if needed.
- // Users can manually delete Settings.xml after verifying the migration was successful.
+ File.Delete(legacyFilePath);
+
+ Log.Info($"Legacy XML settings file backed up to: {backupFilePath}");
Log.Info("Settings migration from XML to JSON completed successfully.");
@@ -182,11 +209,6 @@ private static SettingsInfo DeserializeFromFile(string filePath)
var settingsInfo = JsonSerializer.Deserialize(jsonString, JsonOptions);
- if (settingsInfo == null)
- {
- throw new InvalidOperationException("Failed to deserialize settings from JSON file. The result was null.");
- }
-
return settingsInfo;
}
@@ -195,6 +217,7 @@ private static SettingsInfo DeserializeFromFile(string filePath)
///
/// Path to the XML settings file.
/// Settings as .
+ [Obsolete("Legacy XML settings are no longer used, but the method is kept for migration purposes.")]
private static SettingsInfo DeserializeFromXmlFile(string filePath)
{
var xmlSerializer = new XmlSerializer(typeof(SettingsInfo));
@@ -203,11 +226,6 @@ private static SettingsInfo DeserializeFromXmlFile(string filePath)
var settingsInfo = xmlSerializer.Deserialize(fileStream) as SettingsInfo;
- if (settingsInfo == null)
- {
- throw new InvalidOperationException("Failed to deserialize settings from XML file. The result was null.");
- }
-
return settingsInfo;
}
@@ -239,6 +257,19 @@ private static void SerializeToFile(string filePath)
#endregion
+ #region Backup
+ /*
+ private static void Backup()
+ {
+ Log.Info("Creating settings backup...");
+
+ // Create the backup directory if it does not exist
+ Directory.CreateDirectory(GetSettingsBackupFolderLocation());
+ }
+ */
+
+ #endregion
+
#region Upgrade
///
diff --git a/Source/NETworkManager/App.xaml.cs b/Source/NETworkManager/App.xaml.cs
index b1d067e00e..ace2a1267f 100644
--- a/Source/NETworkManager/App.xaml.cs
+++ b/Source/NETworkManager/App.xaml.cs
@@ -93,15 +93,13 @@ by BornToBeRoot
}
catch (InvalidOperationException ex)
{
- Log.Error("Could not load application settings!");
- Log.Error(ex.Message + "-" + ex.StackTrace);
-
+ Log.Error("Could not load application settings!", ex);
+
HandleCorruptedSettingsFile();
}
catch (JsonException ex)
{
- Log.Error("Could not load application settings! JSON file is corrupted or invalid.");
- Log.Error(ex.Message + "-" + ex.StackTrace);
+ Log.Error("Could not load application settings! JSON file is corrupted or invalid.", ex);
HandleCorruptedSettingsFile();
}
@@ -225,8 +223,10 @@ private void HandleCorruptedSettingsFile()
// Create backup of corrupted file
var destinationFile =
$"{TimestampHelper.GetTimestamp()}_corrupted_" + SettingsManager.GetSettingsFileName();
+
File.Copy(SettingsManager.GetSettingsFilePath(),
Path.Combine(SettingsManager.GetSettingsFolderLocation(), destinationFile));
+
Log.Info($"A backup of the corrupted settings file has been saved under {destinationFile}");
// Initialize default application settings
@@ -283,4 +283,4 @@ private void Save()
ProfileManager.Save();
}
}
-}
\ No newline at end of file
+}
From a2d1f192a0d2ad9fd398dcd55854b9d42f290d31 Mon Sep 17 00:00:00 2001
From: BornToBeRoot <16019165+BornToBeRoot@users.noreply.github.com>
Date: Wed, 24 Dec 2025 17:12:01 +0100
Subject: [PATCH 8/8] Docs: #3282
---
Website/docs/changelog/next-release.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Website/docs/changelog/next-release.md b/Website/docs/changelog/next-release.md
index a06d9051ae..417fc79f9c 100644
--- a/Website/docs/changelog/next-release.md
+++ b/Website/docs/changelog/next-release.md
@@ -51,6 +51,10 @@ Release date: **xx.xx.2025**
- Profile file dialog migrated to a child window to improve usability. [#3227](https://github.com/BornToBeRoot/NETworkManager/pull/3227)
- Credential dialogs migrated to child windows to improve usability. [#3231](https://github.com/BornToBeRoot/NETworkManager/pull/3231)
+**Settings**
+
+- Settings format migrated from `XML` to `JSON`. The settings file will be automatically converted on first start after the update. [#3282](https://github.com/BornToBeRoot/NETworkManager/pull/3282)
+
**DNS Lookup**
- Allow hostname as server address in addition to IP address in the add/edit server dialog. [#3261](https://github.com/BornToBeRoot/NETworkManager/pull/3261)