mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-06 03:07:04 +02:00
[PowerPreview] simplify and use modulesRegistry API
This commit is contained in:
committed by
Andrey Nekrasov
parent
c324cd5953
commit
092ee49139
@@ -5,3 +5,4 @@
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <ProjectTelemetry.h>
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include <common/SettingsAPI/settings_objects.h>
|
||||
#include "powerpreview.h"
|
||||
#include "trace.h"
|
||||
#include "settings.h"
|
||||
#include "Generated Files/resource.h"
|
||||
#include <common/notifications/dont_show_again.h>
|
||||
#include <common/notifications/notifications.h>
|
||||
@@ -10,62 +9,46 @@
|
||||
#include <common/utils/elevation.h>
|
||||
#include <common/utils/resources.h>
|
||||
#include <common/utils/os-detect.h>
|
||||
#include <common/utils/process_path.h>
|
||||
|
||||
// Constructor
|
||||
PowerPreviewModule::PowerPreviewModule() :
|
||||
m_moduleName(GET_RESOURCE_STRING(IDS_MODULE_NAME)),
|
||||
app_key(powerpreviewConstants::ModuleKey)
|
||||
{
|
||||
// Initialize the preview modules.
|
||||
m_fileExplorerModules.emplace_back(std::make_unique<PreviewHandlerSettings>(
|
||||
true,
|
||||
L"svg-previewer-toggle-setting",
|
||||
GET_RESOURCE_STRING(IDS_PREVPANE_SVG_SETTINGS_DESCRIPTION),
|
||||
L"{ddee2b8a-6807-48a6-bb20-2338174ff779}",
|
||||
L"Svg Preview Handler",
|
||||
std::make_unique<RegistryWrapper>()));
|
||||
const std::wstring installationDir = get_module_folderpath();
|
||||
const bool installPerUser = false;
|
||||
m_fileExplorerModules.push_back({ .settingName = L"svg-previewer-toggle-setting",
|
||||
.settingDescription = GET_RESOURCE_STRING(IDS_PREVPANE_SVG_SETTINGS_DESCRIPTION),
|
||||
.registryChanges = getSvgPreviewHandlerChangset(installationDir, installPerUser) });
|
||||
|
||||
m_fileExplorerModules.emplace_back(std::make_unique<PreviewHandlerSettings>(
|
||||
true,
|
||||
L"md-previewer-toggle-setting",
|
||||
GET_RESOURCE_STRING(IDS_PREVPANE_MD_SETTINGS_DESCRIPTION),
|
||||
L"{45769bcc-e8fd-42d0-947e-02beef77a1f5}",
|
||||
L"Markdown Preview Handler",
|
||||
std::make_unique<RegistryWrapper>()));
|
||||
m_fileExplorerModules.push_back({ .settingName = L"md-previewer-toggle-setting",
|
||||
.settingDescription = GET_RESOURCE_STRING(IDS_PREVPANE_MD_SETTINGS_DESCRIPTION),
|
||||
.registryChanges = getMdPreviewHandlerChangset(installationDir, installPerUser) });
|
||||
|
||||
m_fileExplorerModules.emplace_back(std::make_unique<PreviewHandlerSettings>(
|
||||
true,
|
||||
L"pdf-previewer-toggle-setting",
|
||||
GET_RESOURCE_STRING(IDS_PREVPANE_PDF_SETTINGS_DESCRIPTION),
|
||||
L"{07665729-6243-4746-95b7-79579308d1b2}",
|
||||
L"PDF Preview Handler",
|
||||
std::make_unique<RegistryWrapper>()));
|
||||
m_fileExplorerModules.push_back({ .settingName = L"pdf-previewer-toggle-setting",
|
||||
.settingDescription = GET_RESOURCE_STRING(IDS_PREVPANE_PDF_SETTINGS_DESCRIPTION),
|
||||
.registryChanges = getPdfPreviewHandlerChangset(installationDir, installPerUser) });
|
||||
|
||||
m_fileExplorerModules.emplace_back(std::make_unique<ThumbnailProviderSettings>(
|
||||
true,
|
||||
L"svg-thumbnail-toggle-setting",
|
||||
GET_RESOURCE_STRING(IDS_SVG_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION),
|
||||
L"{36B27788-A8BB-4698-A756-DF9F11F64F84}",
|
||||
L"Svg Thumbnail Provider",
|
||||
std::make_unique<RegistryWrapper>(),
|
||||
L".svg\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}"));
|
||||
m_fileExplorerModules.push_back({ .settingName = L"svg-thumbnail-toggle-setting",
|
||||
.settingDescription = GET_RESOURCE_STRING(IDS_SVG_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION),
|
||||
.registryChanges = getSvgThumbnailHandlerChangset(installationDir, installPerUser) });
|
||||
|
||||
// PDF
|
||||
m_fileExplorerModules.emplace_back(std::make_unique<ThumbnailProviderSettings>(
|
||||
true,
|
||||
L"pdf-thumbnail-toggle-setting",
|
||||
GET_RESOURCE_STRING(IDS_PDF_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION),
|
||||
L"{BCC13D15-9720-4CC4-8371-EA74A274741E}",
|
||||
L"Pdf Thumbnail Provider",
|
||||
std::make_unique<RegistryWrapper>(),
|
||||
L".pdf\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}"));
|
||||
m_fileExplorerModules.push_back({ .settingName = L"pdf-thumbnail-toggle-setting",
|
||||
.settingDescription = GET_RESOURCE_STRING(IDS_PDF_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION),
|
||||
.registryChanges = getPdfThumbnailHandlerChangset(installationDir, installPerUser) });
|
||||
|
||||
// Initialize the toggle states for each module.
|
||||
init_settings();
|
||||
try
|
||||
{
|
||||
PowerToysSettings::PowerToyValues settings =
|
||||
PowerToysSettings::PowerToyValues::load_from_settings_file(PowerPreviewModule::get_key());
|
||||
|
||||
// File Explorer might be disabled if user updated from old to new settings.
|
||||
// Initialize the registry state in the constructor as PowerPreviewModule::enable/disable will not be called on startup
|
||||
update_registry_to_match_toggles();
|
||||
apply_settings(settings);
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
Trace::InitSetErrorLoadingFile(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the powertoy and free memory.
|
||||
@@ -109,9 +92,9 @@ bool PowerPreviewModule::get_config(_Out_ wchar_t* buffer, _Out_ int* buffer_siz
|
||||
for (auto& fileExplorerModule : m_fileExplorerModules)
|
||||
{
|
||||
settings.add_bool_toggle(
|
||||
fileExplorerModule->GetToggleSettingName(),
|
||||
fileExplorerModule->GetToggleSettingDescription(),
|
||||
fileExplorerModule->GetToggleSettingState());
|
||||
fileExplorerModule.settingName,
|
||||
fileExplorerModule.settingDescription,
|
||||
fileExplorerModule.registryChanges.isApplied());
|
||||
}
|
||||
|
||||
return settings.serialize_to_buffer(buffer, buffer_size);
|
||||
@@ -122,21 +105,8 @@ void PowerPreviewModule::set_config(const wchar_t* config)
|
||||
{
|
||||
try
|
||||
{
|
||||
PowerToysSettings::PowerToyValues settings = PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
|
||||
|
||||
bool updateSuccess = true;
|
||||
bool isElevated = is_process_elevated(false);
|
||||
for (auto& fileExplorerModule : m_fileExplorerModules)
|
||||
{
|
||||
// The new settings interface does not have a toggle to modify enabled, consider File Explorer to always be enabled
|
||||
updateSuccess = updateSuccess && fileExplorerModule->UpdateState(settings, true, isElevated);
|
||||
}
|
||||
|
||||
if (!updateSuccess)
|
||||
{
|
||||
show_update_warning_message();
|
||||
}
|
||||
|
||||
auto settings = PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
|
||||
apply_settings(settings);
|
||||
settings.save_to_settings_file();
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
@@ -145,135 +115,102 @@ void PowerPreviewModule::set_config(const wchar_t* config)
|
||||
}
|
||||
}
|
||||
|
||||
// Enable preview handlers.
|
||||
void PowerPreviewModule::enable()
|
||||
{
|
||||
if (!this->m_enabled)
|
||||
if (!m_enabled)
|
||||
{
|
||||
Trace::EnabledPowerPreview(true);
|
||||
}
|
||||
|
||||
this->m_enabled = true;
|
||||
m_enabled = true;
|
||||
}
|
||||
|
||||
// Disable active preview handlers.
|
||||
void PowerPreviewModule::disable()
|
||||
{
|
||||
elevation_check_wrapper([this]() {
|
||||
// Check if the process is elevated in order to have permissions to modify HKLM registry
|
||||
if (is_process_elevated(false))
|
||||
{
|
||||
for (auto& fileExplorerModule : m_fileExplorerModules)
|
||||
{
|
||||
fileExplorerModule->Disable();
|
||||
fileExplorerModule.registryChanges.unapply();
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
show_update_warning_message();
|
||||
}
|
||||
|
||||
if (this->m_enabled)
|
||||
if (m_enabled)
|
||||
{
|
||||
Trace::EnabledPowerPreview(false);
|
||||
}
|
||||
|
||||
this->m_enabled = false;
|
||||
m_enabled = false;
|
||||
}
|
||||
|
||||
// Returns if the powertoys is enabled
|
||||
bool PowerPreviewModule::is_enabled()
|
||||
{
|
||||
return this->m_enabled;
|
||||
}
|
||||
|
||||
// Load the settings file.
|
||||
void PowerPreviewModule::init_settings()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Load and parse the settings file for this PowerToy.
|
||||
PowerToysSettings::PowerToyValues settings =
|
||||
PowerToysSettings::PowerToyValues::load_from_settings_file(PowerPreviewModule::get_key());
|
||||
|
||||
// Load settings states.
|
||||
for (auto& fileExplorerModule : m_fileExplorerModules)
|
||||
{
|
||||
fileExplorerModule->LoadState(settings);
|
||||
}
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
Trace::InitSetErrorLoadingFile(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
// Function to check if the registry states need to be updated
|
||||
bool PowerPreviewModule::is_registry_update_required()
|
||||
{
|
||||
for (auto& fileExplorerModule : m_fileExplorerModules)
|
||||
{
|
||||
if (fileExplorerModule->GetToggleSettingState() != fileExplorerModule->CheckRegistryState())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
// Function to warn the user that PowerToys needs to run as administrator for changes to take effect
|
||||
void PowerPreviewModule::show_update_warning_message()
|
||||
{
|
||||
using namespace notifications;
|
||||
if (!is_toast_disabled(PreviewModulesDontShowAgainRegistryPath, PreviewModulesDisableIntervalInDays))
|
||||
if (is_toast_disabled(PreviewModulesDontShowAgainRegistryPath, PreviewModulesDisableIntervalInDays))
|
||||
{
|
||||
std::vector<action_t> actions = {
|
||||
link_button{ GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_OPEN_SETTINGS),
|
||||
L"powertoys://open_settings/" },
|
||||
link_button{ GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_DONT_SHOW_AGAIN),
|
||||
L"powertoys://couldnt_toggle_powerpreview_modules_disable/" }
|
||||
};
|
||||
show_toast_with_activations(GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_DESCRIPTION),
|
||||
GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_TITLE),
|
||||
{},
|
||||
std::move(actions));
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<action_t> actions = {
|
||||
link_button{ GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_OPEN_SETTINGS),
|
||||
L"powertoys://open_settings/" },
|
||||
link_button{ GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_DONT_SHOW_AGAIN),
|
||||
L"powertoys://couldnt_toggle_powerpreview_modules_disable/" }
|
||||
};
|
||||
show_toast_with_activations(GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_DESCRIPTION),
|
||||
GET_RESOURCE_STRING(IDS_FILEEXPLORER_ADMIN_RESTART_WARNING_TITLE),
|
||||
{},
|
||||
std::move(actions));
|
||||
}
|
||||
|
||||
// Function that checks if a registry method is required and if so checks if the process is elevated and accordingly executes the method or shows a warning
|
||||
void PowerPreviewModule::registry_and_elevation_check_wrapper(std::function<void()> method)
|
||||
void PowerPreviewModule::apply_settings(const PowerToysSettings::PowerToyValues& settings)
|
||||
{
|
||||
// Check if a registry update is required
|
||||
if (is_registry_update_required())
|
||||
{
|
||||
elevation_check_wrapper(method);
|
||||
}
|
||||
}
|
||||
|
||||
// Function that checks if the process is elevated and accordingly executes the method or shows a warning
|
||||
void PowerPreviewModule::elevation_check_wrapper(std::function<void()> method)
|
||||
{
|
||||
// Check if the process is elevated in order to have permissions to modify HKLM registry
|
||||
if (is_process_elevated(false))
|
||||
{
|
||||
method();
|
||||
}
|
||||
// Show a warning if it doesn't have permissions
|
||||
else
|
||||
const bool isElevated = is_process_elevated(false);
|
||||
bool notifyShell = false;
|
||||
if (!isElevated)
|
||||
{
|
||||
show_update_warning_message();
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& fileExplorerModule : m_fileExplorerModules)
|
||||
{
|
||||
const auto toggle = settings.get_bool_value(fileExplorerModule.settingName);
|
||||
|
||||
// Skip if no need to update
|
||||
if (!toggle.has_value() || *toggle == fileExplorerModule.registryChanges.isApplied())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// (Un)Apply registry changes depending on the new setting value
|
||||
const bool updated = *toggle ? fileExplorerModule.registryChanges.apply() : fileExplorerModule.registryChanges.unapply();
|
||||
|
||||
if (updated)
|
||||
{
|
||||
notifyShell = true;
|
||||
Trace::PowerPreviewSettingsUpdated(fileExplorerModule.settingName.c_str(), !*toggle, *toggle, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace::PowerPreviewSettingsUpdateFailed(fileExplorerModule.settingName.c_str(), !*toggle, *toggle, true);
|
||||
}
|
||||
}
|
||||
if (notifyShell)
|
||||
{
|
||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Function that updates the registry state to match the toggle states
|
||||
void PowerPreviewModule::update_registry_to_match_toggles()
|
||||
{
|
||||
registry_and_elevation_check_wrapper([this]() {
|
||||
for (auto& fileExplorerModule : m_fileExplorerModules)
|
||||
{
|
||||
if (fileExplorerModule->GetToggleSettingState())
|
||||
{
|
||||
// Enable all the modules with initial state set as true.
|
||||
fileExplorerModule->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
fileExplorerModule->Disable();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
#include "pch.h"
|
||||
#include <interface/powertoy_module_interface.h>
|
||||
#include "trace.h"
|
||||
#include "settings.h"
|
||||
#include "thumbnail_provider.h"
|
||||
#include "preview_handler.h"
|
||||
#include "registry_wrapper.h"
|
||||
#include <powerpreview/powerpreviewConstants.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
using namespace PowerPreviewSettings;
|
||||
#include <common/utils/modulesRegistry.h>
|
||||
#include <common/SettingsAPI/settings_objects.h>
|
||||
|
||||
struct FileExplorerModule
|
||||
{
|
||||
std::wstring settingName;
|
||||
std::wstring settingDescription;
|
||||
registry::Changeset registryChanges;
|
||||
};
|
||||
|
||||
// Implement the PowerToy Module Interface and all the required methods.
|
||||
class PowerPreviewModule : public PowertoyModuleIface
|
||||
@@ -18,25 +22,13 @@ private:
|
||||
// The PowerToy state.
|
||||
bool m_enabled = false;
|
||||
std::wstring m_moduleName;
|
||||
//contains the non localized key of the powertoy
|
||||
// Contains the non localized key of the powertoy
|
||||
std::wstring app_key;
|
||||
std::vector<std::unique_ptr<FileExplorerPreviewSettings>> m_fileExplorerModules;
|
||||
|
||||
// Function to check if the registry states need to be updated
|
||||
bool is_registry_update_required();
|
||||
std::vector<FileExplorerModule> m_fileExplorerModules;
|
||||
|
||||
// Function to warn the user that PowerToys needs to run as administrator for changes to take effect
|
||||
void show_update_warning_message();
|
||||
|
||||
// Function that checks if a registry method is required and if so checks if the process is elevated and accordingly executes the method or shows a warning
|
||||
void registry_and_elevation_check_wrapper(std::function<void()> method);
|
||||
|
||||
// Function that checks if the process is elevated and accordingly executes the method or shows a warning
|
||||
void elevation_check_wrapper(std::function<void()> method);
|
||||
|
||||
// Function that updates the registry state to match the toggle states
|
||||
void update_registry_to_match_toggles();
|
||||
|
||||
void apply_settings(const PowerToysSettings::PowerToyValues& settings);
|
||||
public:
|
||||
PowerPreviewModule();
|
||||
|
||||
@@ -48,5 +40,4 @@ public:
|
||||
virtual void enable();
|
||||
virtual void disable();
|
||||
virtual bool is_enabled();
|
||||
virtual void init_settings();
|
||||
};
|
||||
@@ -44,13 +44,8 @@
|
||||
<ClInclude Include="CLSID.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="powerpreviewConstants.h" />
|
||||
<ClInclude Include="preview_handler.h" />
|
||||
<ClInclude Include="registry_wrapper.h" />
|
||||
<ClInclude Include="registry_wrapper_interface.h" />
|
||||
<ClInclude Include="Generated Files/resource.h" />
|
||||
<None Include="resource.base.h" />
|
||||
<ClInclude Include="settings.h" />
|
||||
<ClInclude Include="thumbnail_provider.h" />
|
||||
<ClInclude Include="trace.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -60,10 +55,6 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="powerpreview.cpp" />
|
||||
<ClInclude Include="powerpreview.h" />
|
||||
<ClCompile Include="preview_handler.cpp" />
|
||||
<ClCompile Include="registry_wrapper.cpp" />
|
||||
<ClCompile Include="settings.cpp" />
|
||||
<ClCompile Include="thumbnail_provider.cpp" />
|
||||
<ClCompile Include="trace.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -10,21 +10,9 @@
|
||||
<ClCompile Include="powerpreview.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="registry_wrapper.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="settings.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="trace.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="preview_handler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="thumbnail_provider.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
@@ -37,24 +25,9 @@
|
||||
<ClInclude Include="powerpreview.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="registry_wrapper.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="registry_wrapper_interface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="settings.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="trace.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="preview_handler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thumbnail_provider.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="powerpreviewConstants.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "preview_handler.h"
|
||||
|
||||
namespace PowerPreviewSettings
|
||||
{
|
||||
const LPCWSTR PreviewHandlerSettings::preview_handlers_subkey = L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers";
|
||||
|
||||
// Function to enable the preview handler in registry
|
||||
LONG PreviewHandlerSettings::Enable()
|
||||
{
|
||||
// Add registry value to enable preview.
|
||||
return this->m_registryWrapper->SetRegistryValue(HKEY_LOCAL_MACHINE, preview_handlers_subkey, this->GetCLSID(), REG_SZ, (LPBYTE)this->GetRegistryValueData().c_str(), (DWORD)(this->GetRegistryValueData().length() * sizeof(wchar_t)));
|
||||
}
|
||||
|
||||
// Function to disable the preview handler in registry
|
||||
LONG PreviewHandlerSettings::Disable()
|
||||
{
|
||||
// Delete the registry key to disable preview.
|
||||
return this->m_registryWrapper->DeleteRegistryValue(HKEY_LOCAL_MACHINE, preview_handlers_subkey, this->GetCLSID());
|
||||
}
|
||||
|
||||
// Function to check if the preview handler is enabled in registry
|
||||
bool PreviewHandlerSettings::CheckRegistryState()
|
||||
{
|
||||
DWORD dataType;
|
||||
DWORD byteCount = 255;
|
||||
wchar_t regValue[255] = { 0 };
|
||||
|
||||
LONG errorCode = this->m_registryWrapper->GetRegistryValue(HKEY_LOCAL_MACHINE, preview_handlers_subkey, this->GetCLSID(), &dataType, regValue, &byteCount);
|
||||
|
||||
// Registry value was found
|
||||
if (errorCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Check if the value type is string
|
||||
if (dataType == REG_SZ)
|
||||
{
|
||||
// Check if the current registry value matches the expected value
|
||||
if (wcscmp(regValue, this->GetRegistryValueData().c_str()) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Function to retrieve the registry subkey
|
||||
LPCWSTR PreviewHandlerSettings::GetSubkey()
|
||||
{
|
||||
return preview_handlers_subkey;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
#include "settings.h"
|
||||
|
||||
namespace PowerPreviewSettings
|
||||
{
|
||||
class PreviewHandlerSettings :
|
||||
public FileExplorerPreviewSettings
|
||||
{
|
||||
private:
|
||||
// Relative(HKLM/HKCU) sub key path of Preview Handlers list in registry. Registry key for Preview Handlers is generally HKLM\Software\Microsoft\Windows\CurrentVersion\PreviewHandlers, and the value name with CLSID of the handler in it is set to the name of the handler
|
||||
static const LPCWSTR preview_handlers_subkey;
|
||||
|
||||
public:
|
||||
PreviewHandlerSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, std::unique_ptr<RegistryWrapperIface> registryWrapper) :
|
||||
FileExplorerPreviewSettings(toggleSettingEnabled, toggleSettingName, toggleSettingDescription, clsid, registryValueData, std::move(registryWrapper))
|
||||
{
|
||||
}
|
||||
|
||||
// Function to enable the preview handler in registry
|
||||
LONG Enable();
|
||||
|
||||
// Function to disable the preview handler in registry
|
||||
LONG Disable();
|
||||
|
||||
// Function to check if the preview handler is enabled in registry
|
||||
bool CheckRegistryState();
|
||||
|
||||
// Function to retrieve the registry subkey
|
||||
static LPCWSTR GetSubkey();
|
||||
};
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "registry_wrapper.h"
|
||||
|
||||
namespace PowerPreviewSettings
|
||||
{
|
||||
LONG RegistryWrapper::SetRegistryValue(HKEY keyScope, LPCWSTR subKey, LPCWSTR valueName, DWORD dwType, CONST BYTE* data, DWORD cbData)
|
||||
{
|
||||
HKEY OpenResult;
|
||||
LONG err = RegOpenKeyExW(keyScope, subKey, 0, KEY_WRITE, &OpenResult);
|
||||
|
||||
if (err == ERROR_SUCCESS)
|
||||
{
|
||||
err = RegSetValueExW(
|
||||
OpenResult,
|
||||
valueName,
|
||||
0, // This parameter is reserved and must be zero.
|
||||
dwType,
|
||||
data,
|
||||
cbData);
|
||||
RegCloseKey(OpenResult);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
LONG RegistryWrapper::GetRegistryValue(HKEY keyScope, LPCWSTR subKey, LPCWSTR valueName, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
|
||||
{
|
||||
HKEY OpenResult;
|
||||
LONG err = RegOpenKeyExW(keyScope, subKey, 0, KEY_READ, &OpenResult);
|
||||
|
||||
if (err == ERROR_SUCCESS)
|
||||
{
|
||||
err = RegGetValueW(
|
||||
OpenResult,
|
||||
NULL,
|
||||
valueName,
|
||||
RRF_RT_ANY,
|
||||
pdwType,
|
||||
pvData,
|
||||
pcbData);
|
||||
RegCloseKey(OpenResult);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
LONG RegistryWrapper::DeleteRegistryValue(HKEY keyScope, LPCWSTR subKey, LPCWSTR valueName)
|
||||
{
|
||||
HKEY OpenResult;
|
||||
LONG err = RegOpenKeyExW(keyScope, subKey, 0, KEY_WRITE, &OpenResult);
|
||||
|
||||
if (err == ERROR_SUCCESS)
|
||||
{
|
||||
err = RegDeleteKeyValueW(
|
||||
OpenResult,
|
||||
NULL,
|
||||
valueName);
|
||||
RegCloseKey(OpenResult);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
#include "registry_wrapper_interface.h"
|
||||
|
||||
namespace PowerPreviewSettings
|
||||
{
|
||||
class RegistryWrapper : public RegistryWrapperIface
|
||||
{
|
||||
public:
|
||||
virtual LONG SetRegistryValue(HKEY keyScope, LPCWSTR subKey, LPCWSTR valueName, DWORD dwType, CONST BYTE* data, DWORD cbData);
|
||||
virtual LONG DeleteRegistryValue(HKEY keyScope, LPCWSTR subKey, LPCWSTR valueName);
|
||||
virtual LONG GetRegistryValue(HKEY keyScope, LPCWSTR subKey, LPCWSTR valueName, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);
|
||||
};
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
class RegistryWrapperIface
|
||||
{
|
||||
public:
|
||||
// Sets a registry value under the mentioned scope(HKCR, HKLM, etc).
|
||||
virtual LONG SetRegistryValue(HKEY keyScope, LPCWSTR subKey, LPCWSTR valueName, DWORD dwType, CONST BYTE* data, DWORD cbData) = 0;
|
||||
|
||||
// Delete a registry value.
|
||||
virtual LONG DeleteRegistryValue(HKEY keyScope, LPCWSTR subKey, LPCWSTR valueName) = 0;
|
||||
|
||||
// Reads a registry value.
|
||||
virtual LONG GetRegistryValue(HKEY keyScope, LPCWSTR subKey, LPCWSTR valueName, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData) = 0;
|
||||
};
|
||||
@@ -1,126 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "settings.h"
|
||||
#include "trace.h"
|
||||
#include <iostream>
|
||||
#include <atlstr.h>
|
||||
#include <powerpreview/thumbnail_provider.h>
|
||||
#include <ShlObj_core.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace PowerPreviewSettings
|
||||
{
|
||||
// Base Settings Class Implementation
|
||||
FileExplorerPreviewSettings::FileExplorerPreviewSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, std::unique_ptr<RegistryWrapperIface> registryWrapper) :
|
||||
m_toggleSettingEnabled(toggleSettingEnabled),
|
||||
m_toggleSettingName(toggleSettingName),
|
||||
m_toggleSettingDescription(toggleSettingDescription),
|
||||
m_clsid(clsid),
|
||||
m_registryValueData(registryValueData),
|
||||
m_registryWrapper(std::move(registryWrapper))
|
||||
{
|
||||
}
|
||||
|
||||
bool FileExplorerPreviewSettings::GetToggleSettingState() const
|
||||
{
|
||||
return this->m_toggleSettingEnabled;
|
||||
}
|
||||
|
||||
void FileExplorerPreviewSettings::UpdateToggleSettingState(bool state)
|
||||
{
|
||||
this->m_toggleSettingEnabled = state;
|
||||
}
|
||||
|
||||
std::wstring FileExplorerPreviewSettings::GetToggleSettingName() const
|
||||
{
|
||||
return this->m_toggleSettingName;
|
||||
}
|
||||
|
||||
std::wstring FileExplorerPreviewSettings::GetToggleSettingDescription() const
|
||||
{
|
||||
return this->m_toggleSettingDescription;
|
||||
}
|
||||
|
||||
LPCWSTR FileExplorerPreviewSettings::GetCLSID() const
|
||||
{
|
||||
return this->m_clsid;
|
||||
}
|
||||
|
||||
std::wstring FileExplorerPreviewSettings::GetRegistryValueData() const
|
||||
{
|
||||
return this->m_registryValueData;
|
||||
}
|
||||
|
||||
// Load initial state of the file explorer module. If no inital state present initialize setting with default value.
|
||||
void FileExplorerPreviewSettings::LoadState(PowerToysSettings::PowerToyValues& settings)
|
||||
{
|
||||
auto toggle = settings.get_bool_value(this->GetToggleSettingName());
|
||||
if (toggle)
|
||||
{
|
||||
// If no existing setting found leave the default initialization value.
|
||||
this->UpdateToggleSettingState(*toggle);
|
||||
}
|
||||
}
|
||||
|
||||
// Manage change in state of file explorer module settings.
|
||||
bool FileExplorerPreviewSettings::UpdateState(PowerToysSettings::PowerToyValues& settings, bool enabled, bool isElevated)
|
||||
{
|
||||
auto toggle = settings.get_bool_value(this->GetToggleSettingName());
|
||||
if (toggle)
|
||||
{
|
||||
auto lastState = this->GetToggleSettingState();
|
||||
auto newState = *toggle;
|
||||
if (lastState != newState)
|
||||
{
|
||||
this->UpdateToggleSettingState(newState);
|
||||
|
||||
// If global setting is enable. Add or remove the file explorer module otherwise just change the UI and save the updated config.
|
||||
if (enabled)
|
||||
{
|
||||
// Check if the registry state does not match the new state, registry needs to be modified
|
||||
if (this->CheckRegistryState() != newState)
|
||||
{
|
||||
if (isElevated)
|
||||
{
|
||||
LONG err;
|
||||
if (lastState)
|
||||
{
|
||||
err = this->Disable();
|
||||
}
|
||||
else
|
||||
{
|
||||
err = this->Enable();
|
||||
}
|
||||
|
||||
if (err == ERROR_SUCCESS)
|
||||
{
|
||||
Trace::PowerPreviewSettingsUpdated(this->GetToggleSettingName().c_str(), lastState, newState, enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace::PowerPreviewSettingsUpdateFailed(this->GetToggleSettingName().c_str(), lastState, newState, enabled);
|
||||
}
|
||||
|
||||
if (dynamic_cast<ThumbnailProviderSettings*>(this))
|
||||
{
|
||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
|
||||
}
|
||||
}
|
||||
// If process is not elevated, return false as it is not possible to update the registry
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// If it matches the new state, no update to registry is required
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace::PowerPreviewSettingsUpdated(this->GetToggleSettingName().c_str(), lastState, newState, enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Generated Files/resource.h"
|
||||
#include <common/SettingsAPI/settings_objects.h>
|
||||
#include "registry_wrapper_interface.h"
|
||||
|
||||
namespace PowerPreviewSettings
|
||||
{
|
||||
// PowerToy Windows Explorer File Preview Settings.
|
||||
class FileExplorerPreviewSettings
|
||||
{
|
||||
private:
|
||||
bool m_toggleSettingEnabled;
|
||||
std::wstring m_toggleSettingName;
|
||||
std::wstring m_toggleSettingDescription;
|
||||
std::wstring m_registryValueData;
|
||||
LPCWSTR m_clsid;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<RegistryWrapperIface> m_registryWrapper;
|
||||
|
||||
public:
|
||||
FileExplorerPreviewSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, std::unique_ptr<RegistryWrapperIface>);
|
||||
|
||||
virtual bool GetToggleSettingState() const;
|
||||
virtual void UpdateToggleSettingState(bool state);
|
||||
virtual std::wstring GetToggleSettingName() const;
|
||||
virtual std::wstring GetToggleSettingDescription() const;
|
||||
virtual LPCWSTR GetCLSID() const;
|
||||
virtual std::wstring GetRegistryValueData() const;
|
||||
virtual void LoadState(PowerToysSettings::PowerToyValues& settings);
|
||||
virtual bool UpdateState(PowerToysSettings::PowerToyValues& settings, bool enabled, bool isElevated);
|
||||
virtual LONG Enable() = 0;
|
||||
virtual LONG Disable() = 0;
|
||||
virtual bool CheckRegistryState() = 0;
|
||||
};
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "thumbnail_provider.h"
|
||||
|
||||
namespace PowerPreviewSettings
|
||||
{
|
||||
// Function to enable the thumbnail provider in registry
|
||||
LONG ThumbnailProviderSettings::Enable()
|
||||
{
|
||||
// Add registry value to enable thumbnail provider.
|
||||
return this->m_registryWrapper->SetRegistryValue(HKEY_CLASSES_ROOT, thumbnail_provider_subkey, nullptr, REG_SZ, (LPBYTE)this->GetCLSID(), (DWORD)(wcslen(this->GetCLSID()) * sizeof(wchar_t)));
|
||||
}
|
||||
|
||||
// Function to disable the thumbnail provider in registry
|
||||
LONG ThumbnailProviderSettings::Disable()
|
||||
{
|
||||
// Delete the registry key to disable thumbnail provider.
|
||||
return this->m_registryWrapper->DeleteRegistryValue(HKEY_CLASSES_ROOT, thumbnail_provider_subkey, nullptr);
|
||||
}
|
||||
|
||||
// Function to check if the thumbnail provider is enabled in registry
|
||||
bool ThumbnailProviderSettings::CheckRegistryState()
|
||||
{
|
||||
DWORD dataType;
|
||||
DWORD byteCount = 255;
|
||||
wchar_t regValue[255] = { 0 };
|
||||
|
||||
LONG errorCode = this->m_registryWrapper->GetRegistryValue(HKEY_CLASSES_ROOT, thumbnail_provider_subkey, nullptr, &dataType, regValue, &byteCount);
|
||||
|
||||
// Registry value was found
|
||||
if (errorCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Check if the value type is string
|
||||
if (dataType == REG_SZ)
|
||||
{
|
||||
// Check if the current registry value matches the expected value
|
||||
if (wcscmp(regValue, this->GetCLSID()) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Function to retrieve the registry subkey
|
||||
LPCWSTR ThumbnailProviderSettings::GetSubkey()
|
||||
{
|
||||
return thumbnail_provider_subkey;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
#include "settings.h"
|
||||
|
||||
namespace PowerPreviewSettings
|
||||
{
|
||||
class ThumbnailProviderSettings :
|
||||
public FileExplorerPreviewSettings
|
||||
{
|
||||
private:
|
||||
// Relative HKCR sub key path of thumbnail provider in registry. Registry key for Thumbnail Providers is generally HKCR\fileExtension\{E357FCCD-A995-4576-B01F-234630154E96}, and the default value in it is set to the CLSID of the provider
|
||||
LPCWSTR thumbnail_provider_subkey;
|
||||
|
||||
public:
|
||||
ThumbnailProviderSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, std::unique_ptr<RegistryWrapperIface> registryWrapper, LPCWSTR subkey) :
|
||||
FileExplorerPreviewSettings(toggleSettingEnabled, toggleSettingName, toggleSettingDescription, clsid, registryValueData, std::move(registryWrapper)), thumbnail_provider_subkey(subkey)
|
||||
{
|
||||
}
|
||||
|
||||
// Function to enable the thumbnail provider in registry
|
||||
LONG Enable();
|
||||
|
||||
// Function to disable the thumbnail provider in registry
|
||||
LONG Disable();
|
||||
|
||||
// Function to check if the thumbnail provider is enabled in registry
|
||||
bool CheckRegistryState();
|
||||
|
||||
// Function to retrieve the registry subkey
|
||||
LPCWSTR GetSubkey();
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user