[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

@@ -90,14 +90,12 @@ public:
}
m_enabled = true;
save_settings();
}
virtual void disable() override
{
Logger::info(L"File Locksmith disabled");
m_enabled = false;
save_settings();
}
virtual bool is_enabled() override
@@ -123,7 +121,7 @@ public:
}
private:
bool m_enabled;
bool m_enabled = false;
bool m_extended_only;
void init_settings()
@@ -136,7 +134,7 @@ private:
void save_settings()
{
auto& settings = FileLocksmithSettingsInstance();
settings.SetEnabled(m_enabled);
m_enabled = FileLocksmithSettingsInstance().GetEnabled();
settings.SetExtendedContextMenuOnly(m_extended_only);
settings.Save();

View File

@@ -18,10 +18,12 @@ static bool LastModifiedTime(const std::wstring& filePath, FILETIME* lpFileTime)
FileLocksmithSettings::FileLocksmithSettings()
{
generalJsonFilePath = PTSettingsHelper::get_powertoys_general_save_file_location();
std::wstring savePath = PTSettingsHelper::get_module_save_folder_location(constants::nonlocalizable::PowerToyKey);
std::error_code ec;
jsonFilePath = savePath + constants::nonlocalizable::DataFilePath;
RefreshEnabledState();
Load();
}
@@ -29,7 +31,6 @@ void FileLocksmithSettings::Save()
{
json::JsonObject jsonData;
jsonData.SetNamedValue(constants::nonlocalizable::JsonKeyEnabled, json::value(settings.enabled));
jsonData.SetNamedValue(constants::nonlocalizable::JsonKeyShowInExtendedContextMenu, json::value(settings.showInExtendedContextMenu));
json::to_file(jsonFilePath, jsonData);
@@ -48,6 +49,32 @@ void FileLocksmithSettings::Load()
}
}
void FileLocksmithSettings::RefreshEnabledState()
{
// Load json settings from data file if it is modified in the meantime.
FILETIME lastModifiedTime{};
if (!(LastModifiedTime(generalJsonFilePath, &lastModifiedTime) &&
CompareFileTime(&lastModifiedTime, &lastLoadedGeneralSettingsTime) == 1))
return;
lastLoadedGeneralSettingsTime = lastModifiedTime;
auto json = json::from_file(generalJsonFilePath);
if (!json)
return;
const json::JsonObject& jsonSettings = json.value();
try
{
json::JsonObject modulesEnabledState;
json::get(jsonSettings, L"enabled", modulesEnabledState, json::JsonObject{});
json::get(modulesEnabledState, L"File Locksmith", settings.enabled, true);
}
catch (const winrt::hresult_error&)
{
}
}
void FileLocksmithSettings::Reload()
{
// Load json settings from data file if it is modified in the meantime.
@@ -67,11 +94,6 @@ void FileLocksmithSettings::ParseJson()
const json::JsonObject& jsonSettings = json.value();
try
{
if (json::has(jsonSettings, constants::nonlocalizable::JsonKeyEnabled, json::JsonValueType::Boolean))
{
settings.enabled = jsonSettings.GetNamedBoolean(constants::nonlocalizable::JsonKeyEnabled);
}
if (json::has(jsonSettings, constants::nonlocalizable::JsonKeyShowInExtendedContextMenu, json::JsonValueType::Boolean))
{
settings.showInExtendedContextMenu = jsonSettings.GetNamedBoolean(constants::nonlocalizable::JsonKeyShowInExtendedContextMenu);

View File

@@ -15,16 +15,10 @@ public:
return true;
if (gpoSetting == powertoys_gpo::gpo_rule_configured_disabled)
return false;
Reload();
RefreshEnabledState();
return settings.enabled;
}
inline void SetEnabled(bool enabled)
{
settings.enabled = enabled;
Save();
}
inline bool GetShowInExtendedContextMenu() const
{
return settings.showInExtendedContextMenu;
@@ -45,12 +39,15 @@ private:
bool showInExtendedContextMenu{ false };
};
void RefreshEnabledState();
void Reload();
void ParseJson();
Settings settings;
std::wstring generalJsonFilePath;
std::wstring jsonFilePath;
FILETIME lastLoadedTime;
FILETIME lastLoadedTime{};
FILETIME lastLoadedGeneralSettingsTime{};
};
FileLocksmithSettings& FileLocksmithSettingsInstance();

View File

@@ -26,6 +26,7 @@ using Microsoft.PowerToys.Settings.UI.Library.Utilities;
// 2023- Included in PowerToys.
// </history>
using Microsoft.Win32;
using Settings.UI.Library.Attributes;
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.Properties.Setting.Values.#LoadIntSetting(System.String,System.Int32)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.Properties.Setting.Values.#SaveSetting(System.String,System.Object)", Justification = "Dotnet port with style preservation")]
@@ -766,6 +767,7 @@ namespace MouseWithoutBorders.Class
}
}
[CmdConfigureIgnore]
internal bool DrawMouseEx
{
get

View File

@@ -11,7 +11,8 @@ namespace
{
const wchar_t c_imageResizerDataFilePath[] = L"\\image-resizer-settings.json";
const wchar_t c_rootRegPath[] = L"Software\\Microsoft\\ImageResizer";
const wchar_t c_enabled[] = L"Enabled";
const wchar_t c_enabled[] = L"enabled";
const wchar_t c_ImageResizer[] = L"Image Resizer";
unsigned int RegReadInteger(const std::wstring& valueName, unsigned int defaultValue)
{
@@ -45,6 +46,7 @@ namespace
CSettings::CSettings()
{
generalJsonFilePath = PTSettingsHelper::get_powertoys_general_save_file_location();
std::wstring oldSavePath = PTSettingsHelper::get_module_save_folder_location(ImageResizerConstants::ModuleOldSaveFolderKey);
std::wstring savePath = PTSettingsHelper::get_module_save_folder_location(ImageResizerConstants::ModuleSaveFolderKey);
std::error_code ec;
@@ -62,8 +64,6 @@ void CSettings::Save()
{
json::JsonObject jsonData;
jsonData.SetNamedValue(c_enabled, json::value(settings.enabled));
json::to_file(jsonFilePath, jsonData);
GetSystemTimeAsFileTime(&lastLoadedTime);
}
@@ -82,6 +82,32 @@ void CSettings::Load()
}
}
void CSettings::RefreshEnabledState()
{
// Load json settings from data file if it is modified in the meantime.
FILETIME lastModifiedTime{};
if (!(LastModifiedTime(generalJsonFilePath, &lastModifiedTime) &&
CompareFileTime(&lastModifiedTime, &lastLoadedGeneralSettingsTime) == 1))
return;
lastLoadedGeneralSettingsTime = lastModifiedTime;
auto json = json::from_file(generalJsonFilePath);
if (!json)
return;
const json::JsonObject& jsonSettings = json.value();
try
{
json::JsonObject modulesEnabledState;
json::get(jsonSettings, c_enabled, modulesEnabledState, json::JsonObject{});
json::get(modulesEnabledState, c_ImageResizer, settings.enabled, true);
}
catch (const winrt::hresult_error&)
{
}
}
void CSettings::Reload()
{
// Load json settings from data file if it is modified in the meantime.
@@ -106,10 +132,7 @@ void CSettings::ParseJson()
const json::JsonObject& jsonSettings = json.value();
try
{
if (json::has(jsonSettings, c_enabled, json::JsonValueType::Boolean))
{
settings.enabled = jsonSettings.GetNamedBoolean(c_enabled);
}
// NB: add any new settings here
}
catch (const winrt::hresult_error&)
{

View File

@@ -1,5 +1,6 @@
#pragma once
#include "pch.h"
#include <common/utils/gpo.h>
class CSettings
@@ -14,16 +15,10 @@ public:
return true;
if (gpoSetting == powertoys_gpo::gpo_rule_configured_disabled)
return false;
Reload();
RefreshEnabledState();
return settings.enabled;
}
inline void SetEnabled(bool enabled)
{
settings.enabled = enabled;
Save();
}
void Save();
void Load();
@@ -33,13 +28,16 @@ private:
bool enabled{ true };
};
void RefreshEnabledState();
void Reload();
void MigrateFromRegistry();
void ParseJson();
Settings settings;
std::wstring jsonFilePath;
std::wstring generalJsonFilePath;
FILETIME lastLoadedTime;
FILETIME lastLoadedGeneralSettingsTime{};
};
CSettings& CSettingsInstance();

View File

@@ -37,7 +37,7 @@ class ImageResizerModule : public PowertoyModuleIface
{
private:
// Enabled by default
bool m_enabled = true;
bool m_enabled = false;
std::wstring app_name;
//contains the non localized key of the powertoy
std::wstring app_key;
@@ -101,7 +101,6 @@ public:
virtual void enable()
{
m_enabled = true;
CSettingsInstance().SetEnabled(m_enabled);
if (package::IsWin11OrGreater())
{
@@ -121,7 +120,6 @@ public:
virtual void disable()
{
m_enabled = false;
CSettingsInstance().SetEnabled(m_enabled);
Trace::EnableImageResizer(m_enabled);
}

View File

@@ -92,7 +92,7 @@ namespace Microsoft.PowerToys.Run.Plugin.PowerToys
_utilities.Add(new Utility(
UtilityKey.PowerOCR,
Resources.Text_Extractor,
generalSettings.Enabled.PowerOCR,
generalSettings.Enabled.PowerOcr,
(_) =>
{
using var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowPowerOCRSharedEvent());
@@ -223,7 +223,7 @@ namespace Microsoft.PowerToys.Run.Plugin.PowerToys
case UtilityKey.ColorPicker: u.Enable(generalSettings.Enabled.ColorPicker); break;
case UtilityKey.FancyZones: u.Enable(generalSettings.Enabled.FancyZones); break;
case UtilityKey.Hosts: u.Enable(generalSettings.Enabled.Hosts); break;
case UtilityKey.PowerOCR: u.Enable(generalSettings.Enabled.PowerOCR); break;
case UtilityKey.PowerOCR: u.Enable(generalSettings.Enabled.PowerOcr); break;
case UtilityKey.MeasureTool: u.Enable(generalSettings.Enabled.MeasureTool); break;
case UtilityKey.ShortcutGuide: u.Enable(generalSettings.Enabled.ShortcutGuide); break;
case UtilityKey.RegistryPreview: u.Enable(generalSettings.Enabled.RegistryPreview); break;

View File

@@ -266,20 +266,25 @@ namespace PowerLauncher
private static void UpdateSettings(PowerLauncherSettings settings)
{
var defaultPlugins = GetDefaultPluginsSettings().ToDictionary(x => x.Id);
var defaultPluginsByName = GetDefaultPluginsSettings().ToDictionary(x => x.Name);
foreach (PowerLauncherPluginSettings plugin in settings.Plugins)
{
if (defaultPlugins.TryGetValue(plugin.Id, out PowerLauncherPluginSettings value))
PowerLauncherPluginSettings value = null;
if ((plugin.Id != null && defaultPlugins.TryGetValue(plugin.Id, out value)) || (!string.IsNullOrEmpty(plugin.Name) && defaultPluginsByName.TryGetValue(plugin.Name, out value)))
{
var additionalOptions = CombineAdditionalOptions(value.AdditionalOptions, plugin.AdditionalOptions);
var enabledPolicyState = GPOWrapper.GetRunPluginEnabledValue(plugin.Id);
plugin.Name = value.Name;
var id = value.Id;
var name = value.Name;
var additionalOptions = plugin.AdditionalOptions != null ? CombineAdditionalOptions(value.AdditionalOptions, plugin.AdditionalOptions) : value.AdditionalOptions;
var enabledPolicyState = GPOWrapper.GetRunPluginEnabledValue(id);
plugin.Name = name;
plugin.Description = value.Description;
plugin.Author = value.Author;
plugin.IconPathDark = value.IconPathDark;
plugin.IconPathLight = value.IconPathLight;
plugin.EnabledPolicyUiState = (int)enabledPolicyState;
defaultPlugins[plugin.Id] = plugin;
defaultPlugins[plugin.Id].AdditionalOptions = additionalOptions;
defaultPlugins[id] = plugin;
defaultPlugins[id].AdditionalOptions = additionalOptions;
}
}

View File

@@ -5,7 +5,6 @@
using System.Text.Json.Serialization;
using ManagedCommon;
using Wox.Plugin;
namespace Wox.Infrastructure.UserSettings

View File

@@ -63,9 +63,6 @@ public:
static HRESULT s_CreateInstance(_In_opt_ IUnknown* punkOuter, _In_ REFIID riid, _Outptr_ void** ppv);
static bool SetEnabled(_In_ bool enabled);
static bool IsEnabled();
private:
~CPowerRenameMenu();

View File

@@ -162,7 +162,7 @@ class PowerRenameModule : public PowertoyModuleIface
{
private:
// Enabled by default
bool m_enabled = true;
bool m_enabled = false;
std::wstring app_name;
//contains the non localized key of the powertoy
std::wstring app_key;
@@ -202,16 +202,13 @@ public:
package::RegisterSparsePackage(path, packageUri);
}
}
save_settings();
}
// Disable the powertoy
virtual void disable()
{
Logger::info(L"PowerRename disabled");
m_enabled = false;
save_settings();
Logger::info(L"PowerRename disabled");
}
// Returns if the powertoy is enabled
@@ -316,8 +313,6 @@ public:
void save_settings()
{
CSettingsInstance().SetEnabled(m_enabled);
CSettingsInstance().Save();
Trace::EnablePowerRename(m_enabled);
}

View File

@@ -33,9 +33,11 @@ namespace
CSettings::CSettings()
{
generalJsonFilePath = PTSettingsHelper::get_powertoys_general_save_file_location();
std::wstring result = PTSettingsHelper::get_module_save_folder_location(PowerRenameConstants::ModuleKey);
jsonFilePath = result + std::wstring(c_powerRenameDataFilePath);
moduleJsonFilePath = result + std::wstring(c_powerRenameDataFilePath);
UIFlagsFilePath = result + std::wstring(c_powerRenameUIFlagsFilePath);
RefreshEnabledState();
Load();
}
@@ -43,7 +45,6 @@ void CSettings::Save()
{
json::JsonObject jsonData;
jsonData.SetNamedValue(c_enabled, json::value(settings.enabled));
jsonData.SetNamedValue(c_showIconOnMenu, json::value(settings.showIconOnMenu));
jsonData.SetNamedValue(c_extendedContextMenuOnly, json::value(settings.extendedContextMenuOnly));
jsonData.SetNamedValue(c_persistState, json::value(settings.persistState));
@@ -51,13 +52,13 @@ void CSettings::Save()
jsonData.SetNamedValue(c_maxMRUSize, json::value(settings.maxMRUSize));
jsonData.SetNamedValue(c_useBoostLib, json::value(settings.useBoostLib));
json::to_file(jsonFilePath, jsonData);
json::to_file(moduleJsonFilePath, jsonData);
GetSystemTimeAsFileTime(&lastLoadedTime);
}
void CSettings::Load()
{
if (!std::filesystem::exists(jsonFilePath))
if (!std::filesystem::exists(moduleJsonFilePath))
{
MigrateFromRegistry();
@@ -71,20 +72,35 @@ void CSettings::Load()
}
}
void CSettings::Reload()
void CSettings::RefreshEnabledState()
{
// Load json settings from data file if it is modified in the meantime.
FILETIME lastModifiedTime{};
if (LastModifiedTime(jsonFilePath, &lastModifiedTime) &&
CompareFileTime(&lastModifiedTime, &lastLoadedTime) == 1)
if (!(LastModifiedTime(generalJsonFilePath, &lastModifiedTime) &&
CompareFileTime(&lastModifiedTime, &lastLoadedGeneralSettingsTime) == 1))
return;
lastLoadedGeneralSettingsTime = lastModifiedTime;
auto json = json::from_file(generalJsonFilePath);
if (!json)
return;
const json::JsonObject& jsonSettings = json.value();
try
{
json::JsonObject modulesEnabledState;
json::get(jsonSettings, L"enabled", modulesEnabledState, json::JsonObject{});
json::get(modulesEnabledState, L"PowerRename", settings.enabled, true);
}
catch (const winrt::hresult_error&)
{
Load();
}
}
void CSettings::MigrateFromRegistry()
{
settings.enabled = GetRegBoolean(c_enabled, true);
//settings.enabled = GetRegBoolean(c_enabled, true);
settings.showIconOnMenu = GetRegBoolean(c_showIconOnMenu, true);
settings.extendedContextMenuOnly = GetRegBoolean(c_extendedContextMenuOnly, false); // Disabled by default.
settings.persistState = GetRegBoolean(c_persistState, true);
@@ -100,16 +116,12 @@ void CSettings::MigrateFromRegistry()
void CSettings::ParseJson()
{
auto json = json::from_file(jsonFilePath);
auto json = json::from_file(moduleJsonFilePath);
if (json)
{
const json::JsonObject& jsonSettings = json.value();
try
{
if (json::has(jsonSettings, c_enabled, json::JsonValueType::Boolean))
{
settings.enabled = jsonSettings.GetNamedBoolean(c_enabled);
}
if (json::has(jsonSettings, c_showIconOnMenu, json::JsonValueType::Boolean))
{
settings.showIconOnMenu = jsonSettings.GetNamedBoolean(c_showIconOnMenu);

View File

@@ -15,16 +15,10 @@ public:
return true;
if (gpoSetting == powertoys_gpo::gpo_rule_configured_disabled)
return false;
Reload();
RefreshEnabledState();
return settings.enabled;
}
inline void SetEnabled(bool enabled)
{
settings.enabled = enabled;
Save();
}
inline bool GetShowIconOnMenu() const
{
return settings.showIconOnMenu;
@@ -112,7 +106,7 @@ private:
unsigned int flags{ 0 };
};
void Reload();
void RefreshEnabledState();
void MigrateFromRegistry();
void ParseJson();
@@ -120,9 +114,11 @@ private:
void WriteFlags();
Settings settings;
std::wstring jsonFilePath;
std::wstring generalJsonFilePath;
std::wstring moduleJsonFilePath;
std::wstring UIFlagsFilePath;
FILETIME lastLoadedTime;
FILETIME lastLoadedTime{};
FILETIME lastLoadedGeneralSettingsTime{};
};
CSettings& CSettingsInstance();