From ea25bd91b011682332bee456a4177444162feaaa Mon Sep 17 00:00:00 2001 From: Roy Date: Fri, 20 Aug 2021 15:36:29 +0200 Subject: [PATCH] Standardize .NET JSON on System.Text.Json (#12805) * Implement System.Text.Json for Community.PowerToys.Run.Plugin.VSCodeWorkspaces (#11697) * Implement System.Text.Json for Community.PowerToys.Run.Plugin.VSCodeWorkspaces * Cleanup property names * Implement System.Text.Json for Microsoft.PowerToys.Settings.UI (#11702) * Implement System.Text.Json for Powerlauncher (#11699) * Implement System.Text.Json for Wox.Infrastructure * Implement System.Text.Json for Powerlauncher * Implement System.Text.Json for Microsoft.Plugin.Folder * Implement System.Text.Json for Wox.Plugin * Remove Newtonsoft.Json from launcherInstallComponent * Update properties with private setter Format JSON output * Serialize Get with private set property * Implement System.Text.Json for ImageResizerUI (#11847) * Implement System.Text.Json for ImageRezierUI * Change Newtonsoft.Json.dll to System.Text.Json in ImageResizer * Add writefile to spelling whitelist * Fix installer * Fix bad merge Co-authored-by: mykhailopylyp <17161067+mykhailopylyp@users.noreply.github.com> --- .github/actions/spell-check/expect.txt | 1 + installer/PowerToysSetup/Product.wxs | 6 +- .../tests/Properties/SettingsTests.cs | 29 ++++++++ .../imageresizer/ui/ImageResizerUI.csproj | 2 +- .../imageresizer/ui/Models/CustomSize.cs | 3 +- .../imageresizer/ui/Models/ResizeSize.cs | 15 ++-- .../imageresizer/ui/Properties/Settings.cs | 71 +++++++++---------- .../ui/Properties/SettingsWrapper.cs | 20 ++++++ .../ui/Properties/WrappedJsonConverter`1.cs | 46 ++++++++++++ .../Properties/WrappedJsonValueConverter.cs | 36 ++++++++++ .../VSCodeRemoteMachinesApi.cs | 13 ++-- .../WorkspacesHelper/OpenedPathsList.cs | 3 + .../WorkspacesHelper/VSCodeStorageFile.cs | 3 + .../WorkspacesHelper/VSCodeWorkspaceEntry.cs | 4 ++ .../WorkspacesHelper/VSCodeWorkspacesApi.cs | 7 +- .../Microsoft.Plugin.Folder/FolderLink.cs | 5 +- .../Microsoft.Plugin.Folder/FolderSettings.cs | 4 -- .../Microsoft.Plugin.Folder.csproj | 1 - .../PowerLauncher/Plugin/PluginConfig.cs | 4 +- .../PowerLauncher/Plugin/PluginInstaller.cs | 4 +- .../PowerLauncher/PowerLauncher.csproj | 1 - .../PowerLauncher/Storage/QueryHistory.cs | 4 +- .../Storage/UserSelectedRecord.cs | 14 ++-- .../launcher/Wox.Infrastructure/Helper.cs | 13 +++- .../Storage/JsonStorage`1.cs | 30 ++++---- .../UserSettings/PowerToysRunSettings.cs | 7 +- .../launcher/Wox.Plugin/PluginMetadata.cs | 4 +- .../launcher/Wox.Plugin/Wox.Plugin.csproj | 1 - .../Microsoft.PowerToys.Settings.UI.csproj | 3 - 29 files changed, 241 insertions(+), 113 deletions(-) create mode 100644 src/modules/imageresizer/ui/Properties/SettingsWrapper.cs create mode 100644 src/modules/imageresizer/ui/Properties/WrappedJsonConverter`1.cs create mode 100644 src/modules/imageresizer/ui/Properties/WrappedJsonValueConverter.cs diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 6a05b919de..e5b890aa3d 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -2380,6 +2380,7 @@ wprintf wprp wregex WResize +writefile wsf wsh wsl diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs index 507a629c86..ab21cd3ff1 100644 --- a/installer/PowerToysSetup/Product.wxs +++ b/installer/PowerToysSetup/Product.wxs @@ -539,7 +539,6 @@ - @@ -553,7 +552,8 @@ - + + @@ -1078,7 +1078,7 @@ - + diff --git a/src/modules/imageresizer/tests/Properties/SettingsTests.cs b/src/modules/imageresizer/tests/Properties/SettingsTests.cs index 799f3e1c68..52f7cac03a 100644 --- a/src/modules/imageresizer/tests/Properties/SettingsTests.cs +++ b/src/modules/imageresizer/tests/Properties/SettingsTests.cs @@ -6,6 +6,7 @@ using System.Collections.Specialized; using System.ComponentModel; using System.Globalization; using System.Linq; +using System.Text.Json; using ImageResizer.Models; using ImageResizer.Test; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -347,6 +348,34 @@ namespace ImageResizer.Properties Assert.IsTrue(selectedSizeIndexChanged); } + [TestMethod] + public void SystemTextJsonDeserializesCorrectly() + { + // Generated Settings file in 0.72 + var defaultInput = + "{\r\n \"properties\": {\r\n \"imageresizer_selectedSizeIndex\": {\r\n \"value\": 1\r\n },\r\n \"imageresizer_shrinkOnly\": {\r\n \"value\": true\r\n },\r\n \"imageresizer_replace\": {\r\n \"value\": true\r\n },\r\n \"imageresizer_ignoreOrientation\": {\r\n \"value\": false\r\n },\r\n \"imageresizer_jpegQualityLevel\": {\r\n \"value\": 91\r\n },\r\n \"imageresizer_pngInterlaceOption\": {\r\n \"value\": 1\r\n },\r\n \"imageresizer_tiffCompressOption\": {\r\n \"value\": 1\r\n },\r\n \"imageresizer_fileName\": {\r\n \"value\": \"%1 %1 (%2)\"\r\n },\r\n \"imageresizer_sizes\": {\r\n \"value\": [\r\n {\r\n \"Id\": 0,\r\n \"ExtraBoxOpacity\": 100,\r\n \"EnableEtraBoxes\": true,\r\n \"name\": \"Small-NotDefault\",\r\n \"fit\": 1,\r\n \"width\": 854,\r\n \"height\": 480,\r\n \"unit\": 3\r\n },\r\n {\r\n \"Id\": 3,\r\n \"ExtraBoxOpacity\": 100,\r\n \"EnableEtraBoxes\": true,\r\n \"name\": \"Phone\",\r\n \"fit\": 1,\r\n \"width\": 320,\r\n \"height\": 568,\r\n \"unit\": 3\r\n }\r\n ]\r\n },\r\n \"imageresizer_keepDateModified\": {\r\n \"value\": false\r\n },\r\n \"imageresizer_fallbackEncoder\": {\r\n \"value\": \"19e4a5aa-5662-4fc5-a0c0-1758028e1057\"\r\n },\r\n \"imageresizer_customSize\": {\r\n \"value\": {\r\n \"Id\": 4,\r\n \"ExtraBoxOpacity\": 100,\r\n \"EnableEtraBoxes\": true,\r\n \"name\": \"custom\",\r\n \"fit\": 1,\r\n \"width\": 1024,\r\n \"height\": 640,\r\n \"unit\": 3\r\n }\r\n }\r\n },\r\n \"name\": \"ImageResizer\",\r\n \"version\": \"1\"\r\n}"; + + // Execute readFile/writefile twice and see if serialized string is still correct + var resultWrapper = JsonSerializer.Deserialize(defaultInput); + var serializedInput = JsonSerializer.Serialize(resultWrapper, new JsonSerializerOptions() { WriteIndented = true }); + var resultWrapper2 = JsonSerializer.Deserialize(serializedInput); + var serializedInput2 = JsonSerializer.Serialize(resultWrapper2, new JsonSerializerOptions() { WriteIndented = true }); + + Assert.AreEqual(serializedInput, serializedInput2); + Assert.AreEqual("ImageResizer", resultWrapper2.Name); + Assert.AreEqual("1", resultWrapper2.Version); + Assert.IsNotNull(resultWrapper2.Properties); + Assert.IsTrue(resultWrapper2.Properties.ShrinkOnly); + Assert.IsTrue(resultWrapper2.Properties.Replace); + Assert.AreEqual(91, resultWrapper2.Properties.JpegQualityLevel); + Assert.AreEqual(1, (int)resultWrapper2.Properties.PngInterlaceOption); + Assert.AreEqual(1, (int)resultWrapper2.Properties.TiffCompressOption); + Assert.AreEqual("%1 %1 (%2)", resultWrapper2.Properties.FileName); + Assert.AreEqual(2, resultWrapper2.Properties.Sizes.Count); + Assert.IsFalse(resultWrapper2.Properties.KeepDateModified); + Assert.AreEqual("Small-NotDefault", resultWrapper2.Properties.Sizes[0].Name); + } + [ClassCleanup] public static void ClassCleanup() { diff --git a/src/modules/imageresizer/ui/ImageResizerUI.csproj b/src/modules/imageresizer/ui/ImageResizerUI.csproj index b2300618a6..65dfb7eb2c 100644 --- a/src/modules/imageresizer/ui/ImageResizerUI.csproj +++ b/src/modules/imageresizer/ui/ImageResizerUI.csproj @@ -66,13 +66,13 @@ - all 12.2.5 + diff --git a/src/modules/imageresizer/ui/Models/CustomSize.cs b/src/modules/imageresizer/ui/Models/CustomSize.cs index 727bb2f5ab..95c6fbc579 100644 --- a/src/modules/imageresizer/ui/Models/CustomSize.cs +++ b/src/modules/imageresizer/ui/Models/CustomSize.cs @@ -2,8 +2,8 @@ // The Brice Lambson licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/ +using System.Text.Json.Serialization; using ImageResizer.Properties; -using Newtonsoft.Json; namespace ImageResizer.Models { @@ -16,6 +16,7 @@ namespace ImageResizer.Models set { /* no-op */ } } + [JsonConstructor] public CustomSize(ResizeFit fit, double width, double height, ResizeUnit unit) { Fit = fit; diff --git a/src/modules/imageresizer/ui/Models/ResizeSize.cs b/src/modules/imageresizer/ui/Models/ResizeSize.cs index eb1ed0d26e..26bd200ef3 100644 --- a/src/modules/imageresizer/ui/Models/ResizeSize.cs +++ b/src/modules/imageresizer/ui/Models/ResizeSize.cs @@ -1,16 +1,15 @@ -// Copyright (c) Brice Lambson +// Copyright (c) Brice Lambson // The Brice Lambson licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/ using System.Collections.Generic; using System.Diagnostics; +using System.Text.Json.Serialization; using ImageResizer.Helpers; using ImageResizer.Properties; -using Newtonsoft.Json; namespace ImageResizer.Models { - [JsonObject(MemberSerialization.OptIn)] public class ResizeSize : Observable { private static readonly IDictionary _tokens = new Dictionary @@ -41,14 +40,14 @@ namespace ImageResizer.Models { } - [JsonProperty(PropertyName = "name")] + [JsonPropertyName("name")] public virtual string Name { get => _name; set => Set(ref _name, ReplaceTokens(value)); } - [JsonProperty(PropertyName = "fit")] + [JsonPropertyName("fit")] public ResizeFit Fit { get => _fit; @@ -63,14 +62,14 @@ namespace ImageResizer.Models } } - [JsonProperty(PropertyName = "width")] + [JsonPropertyName("width")] public double Width { get => _width; set => Set(ref _width, value); } - [JsonProperty(PropertyName = "height")] + [JsonPropertyName("height")] public double Height { get => _height; @@ -86,7 +85,7 @@ namespace ImageResizer.Models public bool HasAuto => Width == 0 || Height == 0 || double.IsNaN(Width) || double.IsNaN(Height); - [JsonProperty(PropertyName = "unit")] + [JsonPropertyName("unit")] public ResizeUnit Unit { get => _unit; diff --git a/src/modules/imageresizer/ui/Properties/Settings.cs b/src/modules/imageresizer/ui/Properties/Settings.cs index b50a3e93f7..b01fd1b18c 100644 --- a/src/modules/imageresizer/ui/Properties/Settings.cs +++ b/src/modules/imageresizer/ui/Properties/Settings.cs @@ -10,16 +10,14 @@ using System.Collections.Specialized; using System.ComponentModel; using System.Globalization; using System.IO.Abstractions; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading; using System.Windows.Media.Imaging; using ImageResizer.Models; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using Newtonsoft.Json.Serialization; namespace ImageResizer.Properties { - [JsonObject(MemberSerialization.OptIn)] public sealed partial class Settings : IDataErrorInfo, INotifyPropertyChanged { private static readonly IFileSystem _fileSystem = new FileSystem(); @@ -63,6 +61,7 @@ namespace ImageResizer.Properties AllSizes = new AllSizesCollection(this); } + [JsonIgnore] public IEnumerable AllSizes { get; set; } // Using OrdinalIgnoreCase since this is internal and used for comparison with symbols @@ -78,6 +77,7 @@ namespace ImageResizer.Properties .Replace("%5", "{4}", StringComparison.OrdinalIgnoreCase) .Replace("%6", "{5}", StringComparison.OrdinalIgnoreCase)); + [JsonIgnore] public ResizeSize SelectedSize { get => SelectedSizeIndex >= 0 && SelectedSizeIndex < Sizes.Count @@ -222,6 +222,7 @@ namespace ImageResizer.Properties private static Settings defaultInstance = new Settings(); + [JsonIgnore] public static Settings Default { get @@ -231,7 +232,8 @@ namespace ImageResizer.Properties } } - [JsonProperty(PropertyName = "imageresizer_selectedSizeIndex")] + [JsonConverter(typeof(WrappedJsonValueConverter))] + [JsonPropertyName("imageresizer_selectedSizeIndex")] public int SelectedSizeIndex { get => _selectedSizeIndex; @@ -242,7 +244,8 @@ namespace ImageResizer.Properties } } - [JsonProperty(PropertyName = "imageresizer_shrinkOnly")] + [JsonConverter(typeof(WrappedJsonValueConverter))] + [JsonPropertyName("imageresizer_shrinkOnly")] public bool ShrinkOnly { get => _shrinkOnly; @@ -253,7 +256,8 @@ namespace ImageResizer.Properties } } - [JsonProperty(PropertyName = "imageresizer_replace")] + [JsonConverter(typeof(WrappedJsonValueConverter))] + [JsonPropertyName("imageresizer_replace")] public bool Replace { get => _replace; @@ -264,7 +268,8 @@ namespace ImageResizer.Properties } } - [JsonProperty(PropertyName = "imageresizer_ignoreOrientation")] + [JsonConverter(typeof(WrappedJsonValueConverter))] + [JsonPropertyName("imageresizer_ignoreOrientation")] public bool IgnoreOrientation { get => _ignoreOrientation; @@ -275,7 +280,8 @@ namespace ImageResizer.Properties } } - [JsonProperty(PropertyName = "imageresizer_jpegQualityLevel")] + [JsonConverter(typeof(WrappedJsonValueConverter))] + [JsonPropertyName("imageresizer_jpegQualityLevel")] public int JpegQualityLevel { get => _jpegQualityLevel; @@ -286,7 +292,8 @@ namespace ImageResizer.Properties } } - [JsonProperty(PropertyName = "imageresizer_pngInterlaceOption")] + [JsonConverter(typeof(WrappedJsonValueConverter))] + [JsonPropertyName("imageresizer_pngInterlaceOption")] public PngInterlaceOption PngInterlaceOption { get => _pngInterlaceOption; @@ -297,7 +304,8 @@ namespace ImageResizer.Properties } } - [JsonProperty(PropertyName = "imageresizer_tiffCompressOption")] + [JsonConverter(typeof(WrappedJsonValueConverter))] + [JsonPropertyName("imageresizer_tiffCompressOption")] public TiffCompressOption TiffCompressOption { get => _tiffCompressOption; @@ -308,7 +316,8 @@ namespace ImageResizer.Properties } } - [JsonProperty(PropertyName = "imageresizer_fileName")] + [JsonConverter(typeof(WrappedJsonValueConverter))] + [JsonPropertyName("imageresizer_fileName")] public string FileName { get => _fileName; @@ -324,10 +333,13 @@ namespace ImageResizer.Properties } } - [JsonProperty(PropertyName = "imageresizer_sizes")] + [JsonInclude] + [JsonConverter(typeof(WrappedJsonValueConverter))] + [JsonPropertyName("imageresizer_sizes")] public ObservableCollection Sizes { get; private set; } - [JsonProperty(PropertyName = "imageresizer_keepDateModified")] + [JsonConverter(typeof(WrappedJsonValueConverter))] + [JsonPropertyName("imageresizer_keepDateModified")] public bool KeepDateModified { get => _keepDateModified; @@ -338,8 +350,9 @@ namespace ImageResizer.Properties } } - [JsonProperty(PropertyName = "imageresizer_fallbackEncoder")] - public System.Guid FallbackEncoder + [JsonConverter(typeof(WrappedJsonValueConverter))] + [JsonPropertyName("imageresizer_fallbackEncoder")] + public Guid FallbackEncoder { get => _fallbackEncoder; set @@ -349,7 +362,8 @@ namespace ImageResizer.Properties } } - [JsonProperty(PropertyName = "imageresizer_customSize")] + [JsonConverter(typeof(WrappedJsonValueConverter))] + [JsonPropertyName("imageresizer_customSize")] public CustomSize CustomSize { get => _customSize; @@ -372,18 +386,7 @@ namespace ImageResizer.Properties public void Save() { _jsonMutex.WaitOne(); - string jsonData = "{\"version\":\"1.0\",\"name\":\"ImageResizer\",\"properties\":"; - string tempJsonData = JsonConvert.SerializeObject(this); - JObject tempSettings = JObject.Parse(tempJsonData); - - // Replace the of the property with { "value": } to be consistent with PowerToys - foreach (var property in tempSettings) - { - tempSettings[property.Key] = new JObject { { "value", property.Value } }; - } - - jsonData += tempSettings.ToString(Formatting.None); - jsonData += "}"; + string jsonData = JsonSerializer.Serialize(new SettingsWrapper() { Properties = this }); // Create directory if it doesn't exist IFileInfo file = _fileSystem.FileInfo.FromFileName(SettingsPath); @@ -405,15 +408,7 @@ namespace ImageResizer.Properties } string jsonData = _fileSystem.File.ReadAllText(SettingsPath); - JObject imageResizerSettings = JObject.Parse(jsonData); - - // Replace the { "value": } with to match the Settings object format - foreach (var property in (JObject)imageResizerSettings["properties"]) - { - imageResizerSettings["properties"][property.Key] = property.Value["value"]; - } - - Settings jsonSettings = JsonConvert.DeserializeObject(imageResizerSettings["properties"].ToString(), new JsonSerializerSettings() { ObjectCreationHandling = ObjectCreationHandling.Replace }); + Settings jsonSettings = JsonSerializer.Deserialize(jsonData)?.Properties; // Needs to be called on the App UI thread as the properties are bound to the UI. App.Current.Dispatcher.Invoke(() => diff --git a/src/modules/imageresizer/ui/Properties/SettingsWrapper.cs b/src/modules/imageresizer/ui/Properties/SettingsWrapper.cs new file mode 100644 index 0000000000..6666562c94 --- /dev/null +++ b/src/modules/imageresizer/ui/Properties/SettingsWrapper.cs @@ -0,0 +1,20 @@ +// Copyright (c) Brice Lambson +// The Brice Lambson licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/ + +using System.Text.Json.Serialization; + +namespace ImageResizer.Properties +{ + public class SettingsWrapper + { + [JsonPropertyName("name")] + public string Name { get; set; } = "ImageResizer"; + + [JsonPropertyName("version")] + public string Version { get; set; } = "1"; + + [JsonPropertyName("properties")] + public Settings Properties { get; set; } + } +} diff --git a/src/modules/imageresizer/ui/Properties/WrappedJsonConverter`1.cs b/src/modules/imageresizer/ui/Properties/WrappedJsonConverter`1.cs new file mode 100644 index 0000000000..341f15c373 --- /dev/null +++ b/src/modules/imageresizer/ui/Properties/WrappedJsonConverter`1.cs @@ -0,0 +1,46 @@ +// Copyright (c) Brice Lambson +// The Brice Lambson licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/ + +using System; +using System.Text.Encodings.Web; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace ImageResizer.Properties +{ + public class WrappedJsonConverter : JsonConverter + { + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + while (reader.Read()) + { + if (reader.GetString() != "value") + { + continue; + } + + var result = (T)JsonSerializer.Deserialize(ref reader, typeof(T), options); + reader.Read(); + return result; + } + + return default; + } + + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + { + if (writer == default) + { + return; + } + + writer.WriteStartObject(); + writer.WritePropertyName("value"); + + JsonSerializer.Serialize(writer, value, typeof(T), options); + + writer.WriteEndObject(); + } + } +} diff --git a/src/modules/imageresizer/ui/Properties/WrappedJsonValueConverter.cs b/src/modules/imageresizer/ui/Properties/WrappedJsonValueConverter.cs new file mode 100644 index 0000000000..80c368bd90 --- /dev/null +++ b/src/modules/imageresizer/ui/Properties/WrappedJsonValueConverter.cs @@ -0,0 +1,36 @@ +// Copyright (c) Brice Lambson +// The Brice Lambson licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/ + +using System; +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace ImageResizer.Properties +{ + public class WrappedJsonValueConverter : JsonConverterFactory + { + public override bool CanConvert(Type typeToConvert) + { + return true; + } + + public override JsonConverter CreateConverter( + Type type, + JsonSerializerOptions options) + { + if (type == null) + { + return null; + } + + Type keyType = type.UnderlyingSystemType; + + JsonConverter converter = (JsonConverter)Activator.CreateInstance( + typeof(WrappedJsonConverter<>).MakeGenericType(keyType)); + + return converter; + } + } +} diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/RemoteMachinesHelper/VSCodeRemoteMachinesApi.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/RemoteMachinesHelper/VSCodeRemoteMachinesApi.cs index 3c35220dde..b00702bf67 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/RemoteMachinesHelper/VSCodeRemoteMachinesApi.cs +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/RemoteMachinesHelper/VSCodeRemoteMachinesApi.cs @@ -5,9 +5,9 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text.Json; using Community.PowerToys.Run.Plugin.VSCodeWorkspaces.SshConfigParser; using Community.PowerToys.Run.Plugin.VSCodeWorkspaces.VSCodeHelper; -using Newtonsoft.Json; using Wox.Plugin.Logger; namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.RemoteMachinesHelper @@ -35,13 +35,14 @@ namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.RemoteMachinesHelper try { - dynamic vscodeSettingsFile = JsonConvert.DeserializeObject(fileContent); - if (vscodeSettingsFile.ContainsKey("remote.SSH.configFile")) + JsonElement vscodeSettingsFile = JsonSerializer.Deserialize(fileContent); + if (vscodeSettingsFile.TryGetProperty("remote.SSH.configFile", out var pathElement)) { - var path = vscodeSettingsFile["remote.SSH.configFile"]; - if (File.Exists(path.Value)) + var path = pathElement.GetString(); + + if (File.Exists(path)) { - foreach (SshHost h in SshConfig.ParseFile(path.Value)) + foreach (SshHost h in SshConfig.ParseFile(path)) { var machine = new VSCodeRemoteMachine(); machine.Host = h.Host; diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/OpenedPathsList.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/OpenedPathsList.cs index bbc7daa71f..80ebd64a71 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/OpenedPathsList.cs +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/OpenedPathsList.cs @@ -3,13 +3,16 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Text.Json.Serialization; namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.WorkspacesHelper { public class OpenedPathsList { + [JsonPropertyName("workspaces3")] public List Workspaces3 { get; set; } + [JsonPropertyName("entries")] public List Entries { get; set; } } } diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeStorageFile.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeStorageFile.cs index 1a7c12a699..dfaf13fa32 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeStorageFile.cs +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeStorageFile.cs @@ -2,10 +2,13 @@ // 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.Text.Json.Serialization; + namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.WorkspacesHelper { public class VSCodeStorageFile { + [JsonPropertyName("openedPathsList")] public OpenedPathsList OpenedPathsList { get; set; } } } diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeWorkspaceEntry.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeWorkspaceEntry.cs index b2072d3a6b..44412ce9b9 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeWorkspaceEntry.cs +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeWorkspaceEntry.cs @@ -2,12 +2,16 @@ // 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.Text.Json.Serialization; + namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.WorkspacesHelper { public class VSCodeWorkspaceEntry { + [JsonPropertyName("folderUri")] public string FolderUri { get; set; } + [JsonPropertyName("label")] public string Label { get; set; } } } diff --git a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeWorkspacesApi.cs b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeWorkspacesApi.cs index b426f19d36..aafa527924 100644 --- a/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeWorkspacesApi.cs +++ b/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/WorkspacesHelper/VSCodeWorkspacesApi.cs @@ -67,12 +67,7 @@ namespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces.WorkspacesHelper try { - var options = new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true, - }; - - VSCodeStorageFile vscodeStorageFile = JsonSerializer.Deserialize(fileContent, options); + VSCodeStorageFile vscodeStorageFile = JsonSerializer.Deserialize(fileContent); if (vscodeStorageFile != null) { diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/FolderLink.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/FolderLink.cs index 2fc79b9f75..c98747f26f 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/FolderLink.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/FolderLink.cs @@ -4,16 +4,15 @@ using System; using System.Linq; -using Newtonsoft.Json; +using System.Text.Json.Serialization; namespace Microsoft.Plugin.Folder { - [JsonObject(MemberSerialization.OptIn)] public class FolderLink { - [JsonProperty] public string Path { get; set; } + [JsonIgnore] public string Nickname => Path.Split(new[] { System.IO.Path.DirectorySeparatorChar }, StringSplitOptions.None) .Last() diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/FolderSettings.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/FolderSettings.cs index f4c813e05d..403d97e57c 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/FolderSettings.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/FolderSettings.cs @@ -3,19 +3,15 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using Newtonsoft.Json; namespace Microsoft.Plugin.Folder { public class FolderSettings { - [JsonProperty] public List FolderLinks { get; } = new List(); - [JsonProperty] public int MaxFolderResults { get; set; } = 50; - [JsonProperty] public int MaxFileResults { get; set; } = 50; } } diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Microsoft.Plugin.Folder.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Microsoft.Plugin.Folder.csproj index 46877d7a23..ff99608320 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Microsoft.Plugin.Folder.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Microsoft.Plugin.Folder.csproj @@ -77,7 +77,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/src/modules/launcher/PowerLauncher/Plugin/PluginConfig.cs b/src/modules/launcher/PowerLauncher/Plugin/PluginConfig.cs index 02abd0710c..d3d94f5c6c 100644 --- a/src/modules/launcher/PowerLauncher/Plugin/PluginConfig.cs +++ b/src/modules/launcher/PowerLauncher/Plugin/PluginConfig.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; using System.IO.Abstractions; using System.Linq; using System.Reflection; -using Newtonsoft.Json; +using System.Text.Json; using Wox.Plugin; using Wox.Plugin.Logger; @@ -79,7 +79,7 @@ namespace PowerLauncher.Plugin PluginMetadata metadata; try { - metadata = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); + metadata = JsonSerializer.Deserialize(File.ReadAllText(configPath)); metadata.PluginDirectory = pluginDirectory; } catch (Exception e) diff --git a/src/modules/launcher/PowerLauncher/Plugin/PluginInstaller.cs b/src/modules/launcher/PowerLauncher/Plugin/PluginInstaller.cs index 33b338bdb7..ee83e0aa62 100644 --- a/src/modules/launcher/PowerLauncher/Plugin/PluginInstaller.cs +++ b/src/modules/launcher/PowerLauncher/Plugin/PluginInstaller.cs @@ -6,9 +6,9 @@ using System; using System.IO; using System.IO.Abstractions; using System.Reflection; +using System.Text.Json; using System.Windows; using ICSharpCode.SharpZipLib.Zip; -using Newtonsoft.Json; using Wox.Plugin; using Wox.Plugin.Logger; @@ -117,7 +117,7 @@ namespace PowerLauncher.Plugin try { - metadata = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); + metadata = JsonSerializer.Deserialize(File.ReadAllText(configPath)); metadata.PluginDirectory = pluginDirectory; } catch (Exception e) diff --git a/src/modules/launcher/PowerLauncher/PowerLauncher.csproj b/src/modules/launcher/PowerLauncher/PowerLauncher.csproj index bc7c6ea37f..ba2d1515df 100644 --- a/src/modules/launcher/PowerLauncher/PowerLauncher.csproj +++ b/src/modules/launcher/PowerLauncher/PowerLauncher.csproj @@ -100,7 +100,6 @@ - all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/modules/launcher/PowerLauncher/Storage/QueryHistory.cs b/src/modules/launcher/PowerLauncher/Storage/QueryHistory.cs index 54c1f7f382..79621dde24 100644 --- a/src/modules/launcher/PowerLauncher/Storage/QueryHistory.cs +++ b/src/modules/launcher/PowerLauncher/Storage/QueryHistory.cs @@ -5,12 +5,14 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json.Serialization; namespace PowerLauncher.Storage { public class QueryHistory { - public List Items { get; } = new List(); + [JsonInclude] + public List Items { get; private set; } = new List(); private readonly int _maxHistory = 300; diff --git a/src/modules/launcher/PowerLauncher/Storage/UserSelectedRecord.cs b/src/modules/launcher/PowerLauncher/Storage/UserSelectedRecord.cs index f5e4a62ec1..b205f0ef72 100644 --- a/src/modules/launcher/PowerLauncher/Storage/UserSelectedRecord.cs +++ b/src/modules/launcher/PowerLauncher/Storage/UserSelectedRecord.cs @@ -4,15 +4,15 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json; +using System.Text.Json.Serialization; using Wox.Plugin; namespace PowerLauncher.Storage { public class UserSelectedRecord { - [JsonProperty] - private readonly Dictionary records = new Dictionary(); + [JsonInclude] + public Dictionary Records { get; private set; } = new Dictionary(); public void Add(Result result) { @@ -22,13 +22,13 @@ namespace PowerLauncher.Storage } var key = result.ToString(); - if (records.TryGetValue(key, out int value)) + if (Records.TryGetValue(key, out int value)) { - records[key] = value + 1; + Records[key] = value + 1; } else { - records.Add(key, 1); + Records.Add(key, 1); } } @@ -39,7 +39,7 @@ namespace PowerLauncher.Storage throw new ArgumentNullException(nameof(result)); } - if (result != null && records.TryGetValue(result.ToString(), out int value)) + if (result != null && Records.TryGetValue(result.ToString(), out int value)) { return value; } diff --git a/src/modules/launcher/Wox.Infrastructure/Helper.cs b/src/modules/launcher/Wox.Infrastructure/Helper.cs index 741a505927..96aa63f119 100644 --- a/src/modules/launcher/Wox.Infrastructure/Helper.cs +++ b/src/modules/launcher/Wox.Infrastructure/Helper.cs @@ -7,8 +7,8 @@ using System.ComponentModel; using System.Diagnostics; using System.IO.Abstractions; using System.Reflection; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; +using System.Text.Json; +using System.Text.Json.Serialization; using Wox.Plugin.Logger; namespace Wox.Infrastructure @@ -81,7 +81,14 @@ namespace Wox.Infrastructure public static string Formatted(this T t) { - var formatted = JsonConvert.SerializeObject(t, Formatting.Indented, new StringEnumConverter()); + var formatted = JsonSerializer.Serialize(t, new JsonSerializerOptions + { + WriteIndented = true, + Converters = + { + new JsonStringEnumConverter(), + }, + }); return formatted; } diff --git a/src/modules/launcher/Wox.Infrastructure/Storage/JsonStorage`1.cs b/src/modules/launcher/Wox.Infrastructure/Storage/JsonStorage`1.cs index d4900d0664..12088202fe 100644 --- a/src/modules/launcher/Wox.Infrastructure/Storage/JsonStorage`1.cs +++ b/src/modules/launcher/Wox.Infrastructure/Storage/JsonStorage`1.cs @@ -6,7 +6,7 @@ using System; using System.Globalization; using System.IO; using System.IO.Abstractions; -using Newtonsoft.Json; +using System.Text.Json; using Wox.Plugin.Logger; namespace Wox.Infrastructure.Storage @@ -20,7 +20,16 @@ namespace Wox.Infrastructure.Storage private static readonly IPath Path = FileSystem.Path; private static readonly IFile File = FileSystem.File; - private readonly JsonSerializerSettings _serializerSettings; + // use property initialization instead of DefaultValueAttribute + // easier and flexible for default value of object + private static readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions + { + IgnoreNullValues = true, + IncludeFields = true, + PropertyNameCaseInsensitive = true, + WriteIndented = true, + }; + private T _data; // need a new directory name @@ -35,17 +44,6 @@ namespace Wox.Infrastructure.Storage private const int _jsonStorage = 1; private StoragePowerToysVersionInfo _storageHelper; - internal JsonStorage() - { - // use property initialization instead of DefaultValueAttribute - // easier and flexible for default value of object - _serializerSettings = new JsonSerializerSettings - { - ObjectCreationHandling = ObjectCreationHandling.Replace, - NullValueHandling = NullValueHandling.Ignore, - }; - } - public T Load() { _storageHelper = new StoragePowerToysVersionInfo(FilePath, _jsonStorage); @@ -84,7 +82,7 @@ namespace Wox.Infrastructure.Storage { try { - _data = JsonConvert.DeserializeObject(serialized, _serializerSettings); + _data = JsonSerializer.Deserialize(serialized, _serializerOptions); } catch (JsonException e) { @@ -105,7 +103,7 @@ namespace Wox.Infrastructure.Storage BackupOriginFile(); } - _data = JsonConvert.DeserializeObject("{}", _serializerSettings); + _data = JsonSerializer.Deserialize("{}", _serializerOptions); Save(); } @@ -126,7 +124,7 @@ namespace Wox.Infrastructure.Storage { try { - string serialized = JsonConvert.SerializeObject(_data, Formatting.Indented); + string serialized = JsonSerializer.Serialize(_data, _serializerOptions); File.WriteAllText(FilePath, serialized); _storageHelper.Close(); diff --git a/src/modules/launcher/Wox.Infrastructure/UserSettings/PowerToysRunSettings.cs b/src/modules/launcher/Wox.Infrastructure/UserSettings/PowerToysRunSettings.cs index c30f98ff53..ed9234699c 100644 --- a/src/modules/launcher/Wox.Infrastructure/UserSettings/PowerToysRunSettings.cs +++ b/src/modules/launcher/Wox.Infrastructure/UserSettings/PowerToysRunSettings.cs @@ -1,13 +1,12 @@ -// Copyright (c) Microsoft Corporation +// 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.Collections.ObjectModel; using System.Drawing; +using System.Text.Json.Serialization; using ManagedCommon; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using Wox.Plugin; namespace Wox.Infrastructure.UserSettings @@ -177,7 +176,7 @@ namespace Wox.Infrastructure.UserSettings public HttpProxy Proxy { get; set; } = new HttpProxy(); - [JsonConverter(typeof(StringEnumConverter))] + [JsonConverter(typeof(JsonStringEnumConverter))] public LastQueryMode LastQueryMode { get; set; } = LastQueryMode.Selected; } diff --git a/src/modules/launcher/Wox.Plugin/PluginMetadata.cs b/src/modules/launcher/Wox.Plugin/PluginMetadata.cs index 1ac2a61658..b21c474e04 100644 --- a/src/modules/launcher/Wox.Plugin/PluginMetadata.cs +++ b/src/modules/launcher/Wox.Plugin/PluginMetadata.cs @@ -6,11 +6,10 @@ using System; using System.Collections.Generic; using System.IO.Abstractions; using System.Linq; -using Newtonsoft.Json; +using System.Text.Json.Serialization; namespace Wox.Plugin { - [JsonObject(MemberSerialization.OptOut)] public class PluginMetadata : BaseModel { private static readonly IFileSystem FileSystem = new FileSystem(); @@ -36,6 +35,7 @@ namespace Wox.Plugin public bool Disabled { get; set; } + [JsonInclude] public string ExecuteFilePath { get; private set; } public string ExecuteFileName { get; set; } diff --git a/src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj b/src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj index 6ce7a44086..a0e6a98387 100644 --- a/src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj +++ b/src/modules/launcher/Wox.Plugin/Wox.Plugin.csproj @@ -69,7 +69,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Microsoft.PowerToys.Settings.UI.csproj b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Microsoft.PowerToys.Settings.UI.csproj index c9a3f78919..119079b125 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Microsoft.PowerToys.Settings.UI.csproj +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Microsoft.PowerToys.Settings.UI.csproj @@ -284,9 +284,6 @@ 2.0.1 - - 13.0.1 - 1.1.118 runtime; build; native; contentfiles; analyzers; buildtransitive