[DSC] Implement Microsoft.PowerToys.Configure DSCResource & winget support (#30918)

* [DSC] Microsoft.PowerToys.Configure module + winget configuration file support

* f: fix for an incorrect directory id reference

* f: update comment

* f: address review comments

* f: file locksmith bug fix

* f: add explorer preview switches in samples

* f: remove debug

* Sign DSC files

* f: implement docs/samples generator

* [ci]Sign FancyZonesEditorCommon.dll

* Sign DSC files in the Generated folder

* f: address review comments

* f: update usable options

* f: add autogenerated sample

* [Installer] Don't use same GUID for different components

* [Installer]Don't remove folders shared by other modules

* Allow configuring PTRun MaximumNumberOfResults

* Remove all settings DSC sample. Just random data

* Allow configuring Hosts Run as Administrator

* Revert "[Installer]Don't remove folders shared by other modules"

This reverts commit 6da3d6cfd5.

* Add all PTRun plugins and Global and keyboard to DSC sample

* Fix issues with context menu modules not disabling

* Fix default enabled values when setting with DSC

* Fix tests regarding default modules in Settings

* Fix merge error

* Restart PowerToys process if we stopped it

---------

Co-authored-by: Andrey Nekrasov <1828123+yuyoyuppe@users.noreply.github.com>
Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
This commit is contained in:
Andrey Nekrasov
2024-04-02 01:09:47 +02:00
committed by GitHub
parent 818d3e3035
commit f23fa3f592
81 changed files with 2608 additions and 265 deletions

View File

@@ -0,0 +1,16 @@
// 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;
namespace Settings.UI.Library.Attributes;
/// <summary>
/// Adding this attribute to a property makes it not configurable from the command line.
/// Typical use cases:
/// - Property represents internal module state.
/// - Property has a type that is unwieldy to type as a command line string.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class CmdConfigureIgnoreAttribute : Attribute;

View File

@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
@@ -36,6 +37,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public DateTimeOffset ExpirationDateTime { get; set; }
[JsonPropertyName("customTrayTimes")]
[CmdConfigureIgnoreAttribute]
public Dictionary<string, int> CustomTrayTimes { get; set; }
}

View File

@@ -7,7 +7,7 @@ using System.Text.Json.Serialization;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class BoolProperty
public record BoolProperty : ICmdLineRepresentable
{
public BoolProperty()
{
@@ -22,9 +22,28 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonPropertyName("value")]
public bool Value { get; set; }
public static bool TryParseFromCmd(string cmd, out object result)
{
result = null;
if (!bool.TryParse(cmd, out bool value))
{
return false;
}
result = new BoolProperty { Value = value };
return true;
}
public override string ToString()
{
return JsonSerializer.Serialize(this);
}
public bool TryToCmdRepresentable(out string result)
{
result = Value.ToString();
return true;
}
}
}

View File

@@ -7,11 +7,13 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library.Enumerations;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class ColorPickerProperties
{
[CmdConfigureIgnore]
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, false, true, 0x43);
public ColorPickerProperties()
@@ -43,6 +45,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonPropertyName("changecursor")]
[JsonConverter(typeof(BoolPropertyJsonConverter))]
[CmdConfigureIgnoreAttribute]
public bool ChangeCursor { get; set; }
[JsonPropertyName("copiedcolorrepresentation")]
@@ -53,12 +56,15 @@ namespace Microsoft.PowerToys.Settings.UI.Library
// Property ColorHistory is not used, the color history is saved separately in the colorHistory.json file
[JsonPropertyName("colorhistory")]
[CmdConfigureIgnoreAttribute]
public List<string> ColorHistory { get; set; }
[JsonPropertyName("colorhistorylimit")]
[CmdConfigureIgnoreAttribute]
public int ColorHistoryLimit { get; set; }
[JsonPropertyName("visiblecolorformats")]
[CmdConfigureIgnoreAttribute]
public Dictionary<string, KeyValuePair<bool, string>> VisibleColorFormats { get; set; }
[JsonPropertyName("showcolorname")]

View File

@@ -15,6 +15,8 @@ namespace Microsoft.PowerToys.Settings.UI.Library
{
private Action notifyEnabledChangedAction;
// Default values for enabled modules should match their expected "enabled by default" values.
// Otherwise, a run of DSC on clean settings will not match the expected default result.
public EnabledModules()
{
}
@@ -55,7 +57,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
private bool fileExplorerPreview = true;
[JsonPropertyName("File Explorer Preview")]
public bool FileExplorerPreview
public bool PowerPreview
{
get => fileExplorerPreview;
set
@@ -116,7 +118,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
}
}
private bool keyboardManager = true;
private bool keyboardManager; // defaulting to off
[JsonPropertyName("Keyboard Manager")]
public bool KeyboardManager
@@ -183,7 +185,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
}
}
private bool awake;
private bool awake = true;
[JsonPropertyName("Awake")]
public bool Awake
@@ -199,7 +201,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
}
}
private bool mouseWithoutBorders = true;
private bool mouseWithoutBorders; // defaulting to off
[JsonPropertyName("MouseWithoutBorders")]
public bool MouseWithoutBorders
@@ -247,7 +249,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
}
}
private bool mouseJump = true;
private bool mouseJump; // defaulting to off
[JsonPropertyName("MouseJump")]
public bool MouseJump
@@ -279,7 +281,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
}
}
private bool mousePointerCrosshairs = true;
private bool mousePointerCrosshairs; // defaulting to off
[JsonPropertyName("MousePointerCrosshairs")]
public bool MousePointerCrosshairs
@@ -295,7 +297,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
}
}
private bool powerAccent;
private bool powerAccent; // defaulting to off
[JsonPropertyName("QuickAccent")]
public bool PowerAccent
@@ -311,10 +313,10 @@ namespace Microsoft.PowerToys.Settings.UI.Library
}
}
private bool powerOCR = true;
private bool powerOCR; // defaulting to off
[JsonPropertyName("TextExtractor")]
public bool PowerOCR
public bool PowerOcr
{
get => powerOCR;
set

View File

@@ -4,6 +4,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
@@ -110,6 +111,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public BoolProperty FancyzonesMakeDraggedWindowTransparent { get; set; }
[JsonPropertyName("fancyzones_allowPopupWindowSnap")]
[CmdConfigureIgnore]
public BoolProperty FancyzonesAllowPopupWindowSnap { get; set; }
[JsonPropertyName("fancyzones_allowChildWindowSnap")]

View File

@@ -3,11 +3,13 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class FindMyMouseProperties
{
[CmdConfigureIgnore]
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, false, true, 0x46);
[JsonPropertyName("activation_method")]

View File

@@ -8,6 +8,7 @@ using System.Text.Json.Serialization;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
@@ -18,15 +19,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public bool Startup { get; set; }
// Gets or sets a value indicating whether the powertoy elevated.
[CmdConfigureIgnoreAttribute]
[JsonPropertyName("is_elevated")]
public bool IsElevated { get; set; }
// Gets or sets a value indicating whether powertoys should run elevated.
[JsonPropertyName("run_elevated")]
[CmdConfigureIgnoreAttribute]
public bool RunElevated { get; set; }
// Gets or sets a value indicating whether is admin.
[JsonPropertyName("is_admin")]
[CmdConfigureIgnoreAttribute]
public bool IsAdmin { get; set; }
// Gets or sets a value indicating whether is warnings of elevated apps enabled.
@@ -39,16 +43,20 @@ namespace Microsoft.PowerToys.Settings.UI.Library
// Gets or sets system theme name.
[JsonPropertyName("system_theme")]
[CmdConfigureIgnore]
public string SystemTheme { get; set; }
// Gets or sets powertoys version number.
[JsonPropertyName("powertoys_version")]
[CmdConfigureIgnore]
public string PowertoysVersion { get; set; }
[JsonPropertyName("action_name")]
[CmdConfigureIgnore]
public string CustomActionName { get; set; }
[JsonPropertyName("enabled")]
[CmdConfigureIgnore]
public EnabledModules Enabled { get; set; }
[JsonPropertyName("show_new_updates_toast_notification")]

View File

@@ -3,10 +3,11 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class GenericProperty<T>
public class GenericProperty<T> : ICmdLineRepresentable
{
[JsonPropertyName("value")]
public T Value { get; set; }
@@ -20,5 +21,25 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public GenericProperty()
{
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1000:Do not declare static members on generic types", Justification = "Adding ICmdLineRepresentable support")]
public static bool TryParseFromCmd(string cmd, out object result)
{
result = null;
if (ICmdLineRepresentable.TryParseFromCmdFor(typeof(T), cmd, out var value))
{
result = new GenericProperty<T> { Value = (T)value };
return true;
}
return false;
}
public bool TryToCmdRepresentable(out string result)
{
result = Value.ToString();
return true;
}
}
}

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
using Settings.UI.Library.Enumerations;
namespace Microsoft.PowerToys.Settings.UI.Library

View File

@@ -2,14 +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;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.Json.Serialization;
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class HotkeySettings
public record HotkeySettings : ICmdLineRepresentable
{
private const int VKTAB = 0x09;
@@ -39,11 +41,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
Code = code;
}
public HotkeySettings Clone()
{
return new HotkeySettings(Win, Ctrl, Alt, Shift, Code);
}
[JsonPropertyName("win")]
public bool Win { get; set; }
@@ -176,5 +173,72 @@ namespace Microsoft.PowerToys.Settings.UI.Library
return false;
}
public static bool TryParseFromCmd(string cmd, out object result)
{
bool win = false, ctrl = false, alt = false, shift = false;
int code = 0;
var parts = cmd.Split('+');
foreach (var part in parts)
{
switch (part.Trim().ToLower(CultureInfo.InvariantCulture))
{
case "win":
win = true;
break;
case "ctrl":
ctrl = true;
break;
case "alt":
alt = true;
break;
case "shift":
shift = true;
break;
default:
if (!TryParseKeyCode(part, out code))
{
result = null;
return false;
}
break;
}
}
result = new HotkeySettings(win, ctrl, alt, shift, code);
return true;
}
private static bool TryParseKeyCode(string key, out int keyCode)
{
// ASCII symbol
if (key.Length == 1 && char.IsLetterOrDigit(key[0]))
{
keyCode = char.ToUpper(key[0], CultureInfo.InvariantCulture);
return true;
}
// VK code
else if (key.Length == 4 && key.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
{
return int.TryParse(key.AsSpan(2), NumberStyles.HexNumber, null, out keyCode);
}
// Alias
else
{
keyCode = (int)Utilities.Helper.GetKeyValue(key);
return keyCode != 0;
}
}
public bool TryToCmdRepresentable(out string result)
{
result = ToString();
result = result.Replace(" ", null);
return true;
}
}
}

View File

@@ -6,6 +6,7 @@ using System;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
@@ -69,6 +70,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public StringProperty ImageresizerFileName { get; set; }
[JsonPropertyName("imageresizer_sizes")]
[CmdConfigureIgnoreAttribute]
public ImageResizerSizes ImageresizerSizes { get; set; }
[JsonPropertyName("imageresizer_keepDateModified")]
@@ -78,6 +80,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public StringProperty ImageresizerFallbackEncoder { get; set; }
[JsonPropertyName("imageresizer_customSize")]
[CmdConfigureIgnoreAttribute]
public ImageResizerCustomSizeProperty ImageresizerCustomSize { get; set; }
public string ToJsonString()

View File

@@ -3,13 +3,14 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Microsoft.PowerToys.Settings.UI.Library
{
// Represents the configuration property of the settings that store Integer type.
public class IntProperty
public record IntProperty : ICmdLineRepresentable
{
public IntProperty()
{
@@ -25,6 +26,19 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonPropertyName("value")]
public int Value { get; set; }
public static bool TryParseFromCmd(string cmd, out object result)
{
result = null;
if (!int.TryParse(cmd, out var value))
{
return false;
}
result = new IntProperty { Value = value };
return true;
}
// Returns a JSON version of the class settings configuration class.
public override string ToString()
{
@@ -40,5 +54,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library
{
throw new NotImplementedException();
}
public bool TryToCmdRepresentable(out string result)
{
result = Value.ToString(CultureInfo.InvariantCulture);
return true;
}
}
}

View File

@@ -0,0 +1,126 @@
// 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.Globalization;
using System.Reflection;
namespace Microsoft.PowerToys.Settings.UI.Library;
/// <summary>
/// A helper interface to allow parsing property values from their command line representation.
/// </summary>
public interface ICmdLineRepresentable
{
public static abstract bool TryParseFromCmd(string cmd, out object result);
public abstract bool TryToCmdRepresentable(out string result);
public static sealed bool TryToCmdRepresentableFor(Type type, object value, out string result)
{
result = null;
if (!typeof(ICmdLineRepresentable).IsAssignableFrom(type))
{
throw new ArgumentException($"{type} doesn't implement {nameof(ICmdLineRepresentable)}");
}
var method = type.GetMethod(nameof(TryToCmdRepresentable));
var parameters = new object[] { result };
if ((bool)method.Invoke(value, parameters))
{
result = (string)parameters[0];
return true;
}
return false;
}
public static sealed bool TryParseFromCmdFor(Type type, string cmd, out object result)
{
result = null;
if (!typeof(ICmdLineRepresentable).IsAssignableFrom(type))
{
throw new ArgumentException($"{type} doesn't implement {nameof(ICmdLineRepresentable)}");
}
var method = type.GetMethod(nameof(TryParseFromCmd), BindingFlags.Static | BindingFlags.Public);
var parameters = new object[] { cmd, null };
if ((bool)method.Invoke(null, parameters))
{
result = parameters[1];
return true;
}
return false;
}
public static sealed object ParseFor(Type type, string cmdRepr)
{
if (type.IsEnum)
{
return Enum.Parse(type, cmdRepr);
}
else if (type.IsPrimitive)
{
if (type == typeof(bool))
{
return bool.Parse(cmdRepr.ToLowerInvariant());
}
else
{
// Converts numeric types like Uint32
return Convert.ChangeType(cmdRepr, type, CultureInfo.InvariantCulture);
}
}
else if (type.IsValueType && type == typeof(DateTimeOffset))
{
if (DateTimeOffset.TryParse(cmdRepr, out var structResult))
{
return structResult;
}
throw new ArgumentException($"Invalid DateTimeOffset format '{cmdRepr}'");
}
else if (type.IsClass)
{
if (type == typeof(string))
{
return cmdRepr;
}
else
{
TryParseFromCmdFor(type, cmdRepr, out var classResult);
return classResult;
}
}
throw new NotImplementedException($"Parsing type {type} is not supported yet");
}
public static string ToCmdRepr(Type type, object value)
{
if (type.IsEnum || type.IsPrimitive)
{
return value.ToString();
}
else if (type.IsValueType && type == typeof(DateTimeOffset))
{
return ((DateTimeOffset)value).ToString("o");
}
else if (type.IsClass)
{
if (type == typeof(string))
{
return (string)value;
}
else
{
TryToCmdRepresentableFor(type, value, out var result);
return result;
}
}
throw new NotImplementedException($"CmdRepr of {type} is not supported yet");
}
}

View File

@@ -2,11 +2,12 @@
// 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.Globalization;
using System.Text.Json.Serialization;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class KeyboardKeysProperty
public record KeyboardKeysProperty : ICmdLineRepresentable
{
public KeyboardKeysProperty()
{
@@ -20,5 +21,24 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonPropertyName("value")]
public HotkeySettings Value { get; set; }
public static bool TryParseFromCmd(string cmd, out object result)
{
if (!HotkeySettings.TryParseFromCmd(cmd, out var hotkey))
{
result = null;
return false;
}
else
{
result = new KeyboardKeysProperty { Value = (HotkeySettings)hotkey };
return true;
}
}
public bool TryToCmdRepresentable(out string result)
{
return Value.TryToCmdRepresentable(out result);
}
}
}

View File

@@ -5,16 +5,19 @@
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class KeyboardManagerProperties
{
[JsonPropertyName("activeConfiguration")]
[CmdConfigureIgnoreAttribute]
public GenericProperty<string> ActiveConfiguration { get; set; }
// List of all Keyboard Configurations.
[JsonPropertyName("keyboardConfigurations")]
[CmdConfigureIgnoreAttribute]
public GenericProperty<List<string>> KeyboardConfigurations { get; set; }
public KeyboardManagerProperties()

View File

@@ -4,12 +4,14 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
using Settings.UI.Library.Enumerations;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class MeasureToolProperties
{
[CmdConfigureIgnore]
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, false, true, 0x4D);
public MeasureToolProperties()
@@ -35,6 +37,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonConverter(typeof(BoolPropertyJsonConverter))]
public bool PerColorChannelEdgeDetection { get; set; }
[CmdConfigureIgnore]
public IntProperty UnitsOfMeasure { get; set; }
public IntProperty PixelTolerance { get; set; }

View File

@@ -3,11 +3,13 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class MouseHighlighterProperties
{
[CmdConfigureIgnore]
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, false, true, 0x48);
[JsonPropertyName("activation_shortcut")]
@@ -20,6 +22,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public StringProperty RightButtonClickColor { get; set; }
[JsonPropertyName("highlight_opacity")]
[CmdConfigureIgnore]
public IntProperty HighlightOpacity { get; set; }
[JsonPropertyName("always_color")]

View File

@@ -3,11 +3,13 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class MouseJumpProperties
{
[CmdConfigureIgnore]
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, false, true, 0x44);
[JsonPropertyName("activation_shortcut")]

View File

@@ -9,7 +9,7 @@ using System.Text.Json.Serialization;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class MouseJumpThumbnailSize : INotifyPropertyChanged
public record MouseJumpThumbnailSize : INotifyPropertyChanged, ICmdLineRepresentable
{
private int _width;
private int _height;
@@ -64,5 +64,30 @@ namespace Microsoft.PowerToys.Settings.UI.Library
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public static bool TryParseFromCmd(string cmd, out object result)
{
result = null;
var parts = cmd.Split('x');
if (parts.Length != 2)
{
return false;
}
if (int.TryParse(parts[0], out int width) && int.TryParse(parts[1], out int height))
{
result = new MouseJumpThumbnailSize { Width = width, Height = height };
return true;
}
return false;
}
public bool TryToCmdRepresentable(out string result)
{
result = $"{Width}x{Height}";
return true;
}
}
}

View File

@@ -3,11 +3,13 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class MousePointerCrosshairsProperties
{
[CmdConfigureIgnore]
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, true, false, 0x50); // Win + Alt + P
[JsonPropertyName("activation_shortcut")]

View File

@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
@@ -23,16 +24,22 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public class MouseWithoutBordersProperties : ICloneable
{
[CmdConfigureIgnore]
public static HotkeySettings DefaultHotKeySwitch2AllPC => new HotkeySettings();
[CmdConfigureIgnore]
public static HotkeySettings DefaultHotKeyLockMachine => new HotkeySettings(true, true, true, false, 0x4C);
[CmdConfigureIgnore]
public static HotkeySettings DefaultHotKeyReconnect => new HotkeySettings(true, true, true, false, 0x52);
[CmdConfigureIgnore]
public static HotkeySettings DefaultHotKeyToggleEasyMouse => new HotkeySettings(true, true, true, false, 0x45);
[CmdConfigureIgnore]
public StringProperty SecurityKey { get; set; }
[CmdConfigureIgnore]
[JsonConverter(typeof(BoolPropertyJsonConverter))]
public bool UseService { get; set; }
@@ -72,42 +79,54 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonConverter(typeof(BoolPropertyJsonConverter))]
public bool ShowClipboardAndNetworkStatusMessages { get; set; }
[CmdConfigureIgnoreAttribute]
public List<string> MachineMatrixString { get; set; }
[CmdConfigureIgnoreAttribute]
public StringProperty MachinePool { get; set; }
[JsonConverter(typeof(BoolPropertyJsonConverter))]
[CmdConfigureIgnoreAttribute]
public bool MatrixOneRow { get; set; }
public IntProperty EasyMouse { get; set; }
[CmdConfigureIgnore]
public IntProperty MachineID { get; set; }
[CmdConfigureIgnoreAttribute]
public IntProperty LastX { get; set; }
[CmdConfigureIgnoreAttribute]
public IntProperty LastY { get; set; }
[CmdConfigureIgnoreAttribute]
public IntProperty PackageID { get; set; }
[JsonConverter(typeof(BoolPropertyJsonConverter))]
[CmdConfigureIgnoreAttribute]
public bool FirstRun { get; set; }
public IntProperty HotKeySwitchMachine { get; set; }
[ObsoleteAttribute("Use ToggleEasyMouseShortcut instead", false)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[CmdConfigureIgnoreAttribute]
public IntProperty HotKeyToggleEasyMouse { get; set; }
[ObsoleteAttribute("Use LockMachineShortcut instead", false)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[CmdConfigureIgnoreAttribute]
public IntProperty HotKeyLockMachine { get; set; }
[ObsoleteAttribute("Use ReconnectShortcut instead", false)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[CmdConfigureIgnoreAttribute]
public IntProperty HotKeyReconnect { get; set; }
[ObsoleteAttribute("Use Switch2AllPCShortcut instead", false)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[CmdConfigureIgnoreAttribute]
public IntProperty HotKeySwitch2AllPC { get; set; }
public HotkeySettings ToggleEasyMouseShortcut { get; set; }
@@ -118,6 +137,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public HotkeySettings Switch2AllPCShortcut { get; set; }
[CmdConfigureIgnoreAttribute]
public IntProperty TCPPort { get; set; }
[JsonConverter(typeof(BoolPropertyJsonConverter))]
@@ -126,8 +146,10 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public StringProperty Name2IP { get; set; }
[JsonConverter(typeof(BoolPropertyJsonConverter))]
[CmdConfigureIgnoreAttribute]
public bool FirstCtrlShiftS { get; set; }
[CmdConfigureIgnoreAttribute]
public StringProperty DeviceID { get; set; }
public MouseWithoutBordersProperties()

View File

@@ -3,11 +3,13 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class PastePlainProperties
{
[CmdConfigureIgnore]
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, true, true, false, 0x56); // Ctrl+Win+Alt+V
public PastePlainProperties()

View File

@@ -3,11 +3,13 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class PeekProperties
{
[CmdConfigureIgnore]
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(false, true, false, false, 0x20);
public PeekProperties()

View File

@@ -4,15 +4,18 @@
using System.Text.Json.Serialization;
using ManagedCommon;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class PowerLauncherProperties
{
[JsonPropertyName("search_result_preference")]
[CmdConfigureIgnoreAttribute]
public string SearchResultPreference { get; set; }
[JsonPropertyName("search_type_preference")]
[CmdConfigureIgnoreAttribute]
public string SearchTypePreference { get; set; }
[JsonPropertyName("maximum_number_of_results")]
@@ -22,18 +25,23 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public HotkeySettings OpenPowerLauncher { get; set; }
[JsonPropertyName("open_file_location")]
[CmdConfigureIgnoreAttribute]
public HotkeySettings OpenFileLocation { get; set; }
[JsonPropertyName("copy_path_location")]
[CmdConfigureIgnoreAttribute]
public HotkeySettings CopyPathLocation { get; set; }
[JsonPropertyName("open_console")]
[CmdConfigureIgnoreAttribute]
public HotkeySettings OpenConsole { get; set; }
[JsonPropertyName("override_win_r_key")]
[CmdConfigureIgnoreAttribute]
public bool OverrideWinkeyR { get; set; }
[JsonPropertyName("override_win_s_key")]
[CmdConfigureIgnoreAttribute]
public bool OverrideWinkeyS { get; set; }
[JsonPropertyName("ignore_hotkeys_in_fullscreen")]
@@ -49,6 +57,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public Theme Theme { get; set; }
[JsonPropertyName("show_plugins_overview")]
[CmdConfigureIgnore]
public int ShowPluginsOverview { get; set; }
[JsonPropertyName("title_fontsize")]
@@ -84,10 +93,13 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonPropertyName("generate_thumbnails_from_files")]
public bool GenerateThumbnailsFromFiles { get; set; }
[CmdConfigureIgnoreAttribute]
public HotkeySettings DefaultOpenPowerLauncher => new HotkeySettings(false, false, true, false, 32);
[CmdConfigureIgnoreAttribute]
public HotkeySettings DefaultOpenFileLocation => new HotkeySettings();
[CmdConfigureIgnoreAttribute]
public HotkeySettings DefaultCopyPathLocation => new HotkeySettings();
public PowerLauncherProperties()

View File

@@ -3,11 +3,13 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class PowerOcrProperties
{
[CmdConfigureIgnore]
public HotkeySettings DefaultActivationShortcut => new HotkeySettings(true, false, false, true, 0x54); // Win+Shift+T
public PowerOcrProperties()

View File

@@ -2,7 +2,9 @@
// 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.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
@@ -16,12 +18,14 @@ namespace Microsoft.PowerToys.Settings.UI.Library
ShowIcon = new BoolProperty();
ExtendedContextMenuOnly = new BoolProperty();
UseBoostLib = new BoolProperty();
Enabled = new BoolProperty();
}
[ObsoleteAttribute("Now controlled from the general settings", false)]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public BoolProperty Enabled { get; set; }
[JsonPropertyName("bool_persist_input")]
[CmdConfigureIgnoreAttribute]
public BoolProperty PersistState { get; set; }
[JsonPropertyName("bool_mru_enabled")]
@@ -31,6 +35,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
public IntProperty MaxMRUSize { get; set; }
[JsonPropertyName("bool_show_icon_on_menu")]
[CmdConfigureIgnoreAttribute]
public BoolProperty ShowIcon { get; set; }
[JsonPropertyName("bool_show_extended_menu")]

View File

@@ -1,8 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\Version.props" />
<Import Project="..\..\Version.props" />
<PropertyGroup>
<TargetFrameworks>net8.0-windows</TargetFrameworks>
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
<TargetFramework>net8.0-windows</TargetFramework>
<Version>$(Version).0</Version>
<Authors>Microsoft Corporation</Authors>
@@ -20,42 +22,42 @@
<RuntimeIdentifier>win-arm64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<None Include="backup_restore_settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<None Include="backup_restore_settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.IO.Abstractions" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.IO.Abstractions" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\interop\PowerToys.Interop.vcxproj" />
<ProjectReference Include="..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\interop\PowerToys.Interop.vcxproj" />
<ProjectReference Include="..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\Resources.Designer.cs">
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\Resources.Designer.cs">
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\Resources.resx">
<SubType>Designer</SubType>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\Resources.resx">
<SubType>Designer</SubType>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@@ -3,11 +3,13 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class ShortcutGuideProperties
{
[CmdConfigureIgnore]
public HotkeySettings DefaultOpenShortcutGuide => new HotkeySettings(true, false, false, true, 0xBF);
public ShortcutGuideProperties()

View File

@@ -8,7 +8,7 @@ using System.Text.Json.Serialization;
namespace Microsoft.PowerToys.Settings.UI.Library
{
// Represents the configuration property of the settings that store string type.
public class StringProperty
public record StringProperty : ICmdLineRepresentable
{
public StringProperty()
{
@@ -35,6 +35,18 @@ namespace Microsoft.PowerToys.Settings.UI.Library
return new StringProperty(v);
}
public static bool TryParseFromCmd(string cmd, out object result)
{
result = new StringProperty(cmd);
return true;
}
public bool TryToCmdRepresentable(out string result)
{
result = Value;
return true;
}
public static implicit operator StringProperty(string v)
{
return new StringProperty(v);

View File

@@ -0,0 +1,81 @@
// 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.Linq;
using System.Reflection;
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
namespace Microsoft.PowerToys.Settings.UI.Library;
public class CommandLineUtils
{
private static Type GetSettingsConfigType(string moduleName, Assembly settingsLibraryAssembly)
{
var settingsClassName = moduleName == "GeneralSettings" ? moduleName : moduleName + "Settings";
return settingsLibraryAssembly.GetType(typeof(CommandLineUtils).Namespace + "." + settingsClassName);
}
public static ISettingsConfig GetSettingsConfigFor(string moduleName, ISettingsUtils settingsUtils, Assembly settingsLibraryAssembly)
{
return GetSettingsConfigFor(GetSettingsConfigType(moduleName, settingsLibraryAssembly), settingsUtils);
}
/// Executes SettingsRepository<moduleSettingsType>.GetInstance(settingsUtils).SettingsConfig
public static ISettingsConfig GetSettingsConfigFor(Type moduleSettingsType, ISettingsUtils settingsUtils)
{
var genericSettingsRepositoryType = typeof(SettingsRepository<>);
var moduleSettingsRepositoryType = genericSettingsRepositoryType.MakeGenericType(moduleSettingsType);
// Note: GeneralSettings is only used here only to satisfy nameof constrains, i.e. the choice of this particular type doesn't have any special significance.
var getInstanceInfo = moduleSettingsRepositoryType.GetMethod(nameof(SettingsRepository<GeneralSettings>.GetInstance));
var settingsRepository = getInstanceInfo.Invoke(null, new object[] { settingsUtils });
var settingsConfigProperty = getInstanceInfo.ReturnType.GetProperty(nameof(SettingsRepository<GeneralSettings>.SettingsConfig));
return settingsConfigProperty.GetValue(settingsRepository) as ISettingsConfig;
}
public static Assembly GetSettingsAssembly()
{
return AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName().Name == "PowerToys.Settings.UI.Lib");
}
public static object GetPropertyValue(string propertyName, ISettingsConfig settingsConfig)
{
var (settingInfo, properties) = LocateSetting(propertyName, settingsConfig);
return settingInfo.GetValue(properties);
}
public static object GetProperties(ISettingsConfig settingsConfig)
{
var settingsType = settingsConfig.GetType();
if (settingsType == typeof(GeneralSettings))
{
return settingsConfig;
}
var settingsConfigInfo = settingsType.GetProperty("Properties");
return settingsConfigInfo.GetValue(settingsConfig);
}
public static (PropertyInfo SettingInfo, object Properties) LocateSetting(string propertyName, ISettingsConfig settingsConfig)
{
var properties = GetProperties(settingsConfig);
var propertiesType = properties.GetType();
if (propertiesType == typeof(GeneralSettings) && propertyName.StartsWith("Enabled.", StringComparison.InvariantCulture))
{
var moduleNameToToggle = propertyName.Replace("Enabled.", string.Empty);
properties = propertiesType.GetProperty("Enabled").GetValue(properties);
propertiesType = properties.GetType();
propertyName = moduleNameToToggle;
}
return (propertiesType.GetProperty(propertyName), properties);
}
public static PropertyInfo GetSettingPropertyInfo(string propertyName, ISettingsConfig settingsConfig)
{
return LocateSetting(propertyName, settingsConfig).SettingInfo;
}
}

View File

@@ -0,0 +1,78 @@
// 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.Generic;
using System.Globalization;
using System.Text.Json;
using System.Xml;
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library;
/// <summary>
/// This user flow allows DSC resources to use PowerToys.Settings executable to get settings values by querying them from command line using the following syntax:
/// PowerToys.Settings.exe get <path to a json file containing a list of modules and their corresponding properties>
///
/// Example: PowerToys.Settings.exe get %TEMP%\properties.json
/// `properties.json` file contents:
/// {
/// "AlwaysOnTop": ["FrameEnabled", "FrameAccentColor"],
/// "FancyZones": ["FancyzonesShiftDrag", "FancyzonesShowOnAllMonitors"]
/// }
///
/// Upon PowerToys.Settings.exe completion, it'll update `properties.json` file to contain something like this:
/// {
/// "AlwaysOnTop": {
/// "FrameEnabled": true,
/// "FrameAccentColor": "#0099cc"
/// },
/// "FancyZones": {
/// "FancyzonesShiftDrag": true,
/// "FancyzonesShowOnAllMonitors": false
/// }
/// }
/// </summary>
public sealed class GetSettingCommandLineCommand
{
private static JsonSerializerOptions _serializerOptions = new JsonSerializerOptions
{
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
};
public static string Execute(Dictionary<string, List<string>> settingNamesForModules)
{
var modulesSettings = new Dictionary<string, Dictionary<string, object>>();
var settingsAssembly = CommandLineUtils.GetSettingsAssembly();
var settingsUtils = new SettingsUtils();
var enabledModules = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.Enabled;
foreach (var (moduleName, settings) in settingNamesForModules)
{
var moduleSettings = new Dictionary<string, object>();
if (moduleName != nameof(GeneralSettings))
{
moduleSettings.Add("Enabled", typeof(EnabledModules).GetProperty(moduleName).GetValue(enabledModules));
}
var settingsConfig = CommandLineUtils.GetSettingsConfigFor(moduleName, settingsUtils, settingsAssembly);
foreach (var settingName in settings)
{
var value = CommandLineUtils.GetPropertyValue(settingName, settingsConfig);
if (value != null)
{
var cmdReprValue = ICmdLineRepresentable.ToCmdRepr(value.GetType(), value);
moduleSettings.Add(settingName, cmdReprValue);
}
}
modulesSettings.Add(moduleName, moduleSettings);
}
return JsonSerializer.Serialize(modulesSettings, _serializerOptions);
}
}

View File

@@ -103,6 +103,11 @@ namespace Microsoft.PowerToys.Settings.UI.Library.Utilities
return LayoutMap.GetKeyName(key);
}
public static uint GetKeyValue(string key)
{
return LayoutMap.GetKeyValue(key);
}
public static string GetProductVersion()
{
return interop.CommonManaged.GetProductVersion();

View File

@@ -0,0 +1,109 @@
// 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.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Nodes;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library;
/// <summary>
/// This user flow allows DSC resources to use PowerToys.Settings executable to set custom settings values by suppling them from command line using the following syntax:
/// PowerToys.Settings.exe setAdditional <module struct name> <path to a json file containing the properties>
/// </summary>
public sealed class SetAdditionalSettingsCommandLineCommand
{
private static readonly string KeyPropertyName = "Name";
private static JsonSerializerOptions _serializerOptions = new JsonSerializerOptions
{
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
};
private struct AdditionalPropertyInfo
{
public string RootPropertyName;
public JsonValueKind RootObjectType;
}
private static readonly Dictionary<string, AdditionalPropertyInfo> SupportedAdditionalPropertiesInfoForModules = new Dictionary<string, AdditionalPropertyInfo> { { "PowerLauncher", new AdditionalPropertyInfo { RootPropertyName = "Plugins", RootObjectType = JsonValueKind.Array } } };
private static void ExecuteRootArray(JsonElement.ArrayEnumerator properties, IEnumerable<object> currentPropertyValuesArray)
{
// In case it's an array of object -> combine the existing values with the provided
var currentPropertyValueType = currentPropertyValuesArray.FirstOrDefault()?.GetType();
object matchedElement = null;
foreach (var arrayElement in properties)
{
var newElementPropertyValues = new Dictionary<string, object>();
foreach (var elementProperty in arrayElement.EnumerateObject())
{
var elementPropertyName = elementProperty.Name;
var elementPropertyType = currentPropertyValueType.GetProperty(elementPropertyName).PropertyType;
var elemePropertyValue = ICmdLineRepresentable.ParseFor(elementPropertyType, elementProperty.Value.ToString());
if (elementPropertyName == KeyPropertyName)
{
foreach (var currentElementValue in currentPropertyValuesArray)
{
var currentElementType = currentElementValue.GetType();
var keyPropertyNameInfo = currentElementType.GetProperty(KeyPropertyName);
var keyPropertyValue = keyPropertyNameInfo.GetValue(currentElementValue);
if (string.Equals(keyPropertyValue, elemePropertyValue))
{
matchedElement = currentElementValue;
break;
}
}
}
else
{
newElementPropertyValues.Add(elementPropertyName, elemePropertyValue);
}
}
if (matchedElement != null)
{
foreach (var overriddenProperty in newElementPropertyValues)
{
var propertyInfo = currentPropertyValueType.GetProperty(overriddenProperty.Key);
propertyInfo.SetValue(matchedElement, overriddenProperty.Value);
}
}
}
}
public static void Execute(string moduleName, JsonDocument settings, ISettingsUtils settingsUtils)
{
Assembly settingsLibraryAssembly = CommandLineUtils.GetSettingsAssembly();
var settingsConfig = CommandLineUtils.GetSettingsConfigFor(moduleName, settingsUtils, settingsLibraryAssembly);
var settingsConfigType = settingsConfig.GetType();
if (!SupportedAdditionalPropertiesInfoForModules.TryGetValue(moduleName, out var additionalPropertiesInfo))
{
return;
}
var propertyValueInfo = settingsConfigType.GetProperty(additionalPropertiesInfo.RootPropertyName);
var currentPropertyValue = propertyValueInfo.GetValue(settingsConfig);
// For now, only a certain data shapes are supported
switch (additionalPropertiesInfo.RootObjectType)
{
case JsonValueKind.Array:
ExecuteRootArray(settings.RootElement.EnumerateArray(), currentPropertyValue as IEnumerable<object>);
break;
default:
throw new NotImplementedException();
}
settingsUtils.SaveSettings(settingsConfig.ToJsonString(), settingsConfig.GetModuleName());
}
}

View File

@@ -0,0 +1,53 @@
// 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.Reflection;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library;
/// <summary>
/// This user flow allows DSC resources to use PowerToys.Settings executable to set settings values by suppling them from command line using the following syntax:
/// PowerToys.Settings.exe set <module struct name>.<field name> <field_value>
///
/// Example: PowerToys.Settings.exe set MeasureTool.MeasureCrossColor "#00FF00"
/// </summary>
public sealed class SetSettingCommandLineCommand
{
private static readonly char[] SettingNameSeparator = { '.' };
private static (string ModuleName, string PropertyName) ParseSettingName(string settingName)
{
var parts = settingName.Split(SettingNameSeparator, 2, StringSplitOptions.RemoveEmptyEntries);
return (parts[0], parts[1]);
}
public static void Execute(string settingName, string settingValue, ISettingsUtils settingsUtils)
{
Assembly settingsLibraryAssembly = CommandLineUtils.GetSettingsAssembly();
var (moduleName, propertyName) = ParseSettingName(settingName);
var settingsConfig = CommandLineUtils.GetSettingsConfigFor(moduleName, settingsUtils, settingsLibraryAssembly);
var propertyInfo = CommandLineUtils.GetSettingPropertyInfo(propertyName, settingsConfig);
if (propertyInfo == null)
{
throw new ArgumentException($"Property '{propertyName}' wasn't found");
}
if (propertyInfo.PropertyType.GetCustomAttribute<CmdConfigureIgnoreAttribute>() != null)
{
throw new ArgumentException($"Property '{propertyName}' is explicitly ignored");
}
// Execute settingsConfig.Properties.<propertyName> = settingValue
var propertyValue = ICmdLineRepresentable.ParseFor(propertyInfo.PropertyType, settingValue);
var (settingInfo, properties) = CommandLineUtils.LocateSetting(propertyName, settingsConfig);
settingInfo.SetValue(properties, propertyValue);
settingsUtils.SaveSettings(settingsConfig.ToJsonString(), settingsConfig.GetModuleName());
}
}

View File

@@ -4,11 +4,13 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Settings.UI.Library.Attributes;
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class VideoConferenceConfigProperties
{
[CmdConfigureIgnoreAttribute]
public HotkeySettings DefaultMuteCameraAndMicrophoneHotkey => new HotkeySettings()
{
Win = true,
@@ -19,6 +21,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
Code = 81,
};
[CmdConfigureIgnoreAttribute]
public HotkeySettings DefaultMuteMicrophoneHotkey => new HotkeySettings()
{
Win = true,
@@ -29,6 +32,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
Code = 65,
};
[CmdConfigureIgnoreAttribute]
public HotkeySettings DefaultPushToTalkMicrophoneHotkey => new HotkeySettings()
{
Win = true,
@@ -39,6 +43,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
Code = 73,
};
[CmdConfigureIgnoreAttribute]
public HotkeySettings DefaultMuteCameraHotkey => new HotkeySettings()
{
Win = true,

View File

@@ -9,10 +9,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library
{
public class VideoConferenceSettings : BasePTModuleSettings, ISettingsConfig
{
public const string ModuleName = "Video Conference";
public VideoConferenceSettings()
{
Version = "1";
Name = "Video Conference";
Name = ModuleName;
Properties = new VideoConferenceConfigProperties();
}