[0.16]: Merge Preview Handlers in Master (#1516)

* Added project template for common library

* Added reference to stylecop.json

* Fixed xml documetation file path for common project

* Added reference to stylecop.json

* Added COM interface interpolations to C#

* Changed namespace to Common

* Added xml doc to com interfaces

* Removed AnyCPU configuration from solution file

* Added Preview Hander and form User Control Implementation

* Fix stylecop warnings

* Added test control and handler

* Added Xaml description for preview handler

* Added Xml documenatation

* Updated the control to form

* Added registration and unregistration logic for the handler

* Moved the files in separate folder and fix PR comments

* updated the name of previewhandler class to base class

* Added the DoPreview to PreviewHandlerControl Interface

* Modified the Dopreview and Unload as virtual method

* Uncommented the DocumentText to help bug repro

* HTML Parsing Extension for preview pane markdown renderer (#1108)

* Added Extension for html post processing

* Added unit test poroject for preview pane

* Added pipline test and base test function

* Added Tests for extension

* Added tests for url slashes

* Added tests for url and figure caption

* Markdown preview pane (#1128)

* Added Extension for html post processing

* Added unit test poroject for preview pane

* Added pipline test and base test function

* Added Tests for extension

* Added handler and control for markdown

* Tests added

* Locally working version for markdown

* Working image relative url's in markdown

* Added CSS to preview display

* Updates CSS for code block

* Removed html file write comment in markdown control

* Updated assembly version and web browser control test

* Add Svg preview handler (#1129)

* Added a new project for Svg preview handler

* Added initial implementation of Svg Preview Handler

* Fixed output path

* Added Unit Test Project

* Added StreamWrapper and Update Svg Control

* Updated Svg Handler Guid

* Removed migration backup folder

* Removed Fluent Assertions NuGet

* Added Comments for StreamWrapper

* Removed the manual GC collect

* Added unit tests for Svg preview Handler

* Updated the xml doc for stream wrapper

* User/lamotile/add_powerpreviewsettings (#1075)

* Added powersettings to PowerToys Settings UI

* added settings library

* updated settings-web

* updated project oncfiguration

* updated project onfiguration

* updated project .sln file

* removed .etl file and added it to git-ignore

* separated the PowerPreviewModule into split classes .cpp and .h

* moved PowerPreviewModule implemnetations to .cpp file

* fixed StringTable formatter

* fixed spacing in resource.h

* added m_ to member varibales

* initiliaze m_isPreviewEnabled in the base class

* removed duplication of objects by using pass by refference and std::move

* made the getters const

* updated naming convention

* Split test calsses

* Add const string

* Replaced move with const string

* Made attributes private

* Made attributes private

* removed unused constructor

* Update resource.h

formatted resource.h

* Adding unit tests for preview handler common (#1156)

* Changed the name of the Common library to PreviewHandlerCommon

* Added unit tests project for PreviewHandlerCommon

* Updated ComInterop accessor type

* Added unit tests for PreviewHandlerbase

* Added tests for file and stream based handler

* Added unit tests for StreamWrapper

* Added form handler unit tests

* Added Unit tests for FormHandlerControl

* Added file header

* Add Powerpreview project

* Add spacing in sln file

* swapped string refferences (#1199)

* added registry methods and enable/disable preview handlers (#1230)

* added registry methods and enable/disable preview handlers

* formatted .rc file.

* formatted resource file

* formatted .rc file.

* formatted settings.cpp

* formatted settings.h

* formatted SVGPreviewSettingsClassTest.cpp

* Formatted MarkDownPreviewSettingsClassTest.cpp

* using wide strings

* formatted settings.h

* FileExplorerPreviewSettingsTest.cpp formatting

* fixed typo and formatting

* closing Registry and fixing typos

* formmarted code using ctrl+k+d

* fixed naming

* fixed typo

* changed if/else reverse order

* Markdown preview pane  (#1220)

* Added rich text bar for information display

* Added infobar

* Added tests for extension and markdown control

* Added xml docstring for markdown preview handler control

* Updated assembly file for markdown preview pane

* Updated removal of script tag without modifying CSS

* Added info bar text string to resource file.

* Removed error with infobar display on first rendering

* Updated assembly version

* Remove script and image element from Svg (#1231)

* Added implementation to remove script and image tag

* Added Unit tests for SvgPreviewHandlerHelper

* Updated Unit tests for SvgPreviewControl

* Moved the hardcoded string to resource file

* Changed the LocalMachine to CurrentUser for preview handler registration

* Added unit tests for multiple blocked elements tags

* User/lamotile/update settings objects (#1263)

* added registry methods and enable/disable preview handlers

* formatted .rc file.

* formatted resource file

* formatted .rc file.

* formatted settings.cpp

* formatted settings.h

* formatted SVGPreviewSettingsClassTest.cpp

* Formatted MarkDownPreviewSettingsClassTest.cpp

* using wide strings

* formatted settings.h

* FileExplorerPreviewSettingsTest.cpp formatting

* fixed typo and formatting

* closing Registry and fixing typos

* formmarted code using ctrl+k+d

* fixed naming

* fixed typo

* changed if/else reverse order

* updated setiings_objects.cpp

* removed changes on files that are not part of this PR

* removed const ref on primative types

* updated pass by ref semantic and removed pas by reff on primative types

* fixed spaces in the commas

* fixed spaces in brackets

* Preview pane telemetry (#1299)

* Added telemetry base class and markdown telemetry class

* Updated docstring for telemetry event.

* Added telemetry to markdown for error

* Added try catch for markdown preview handler and display error bar

* Updated markdown telemetry to make event names global variable

* Updated parameter name to camel casing and telemetry event name naming.

* Corrected assembbly version for svg renderer

* Markdown Image files display (#1303)

* Added telemetry base class and markdown telemetry class

* Updated docstring for telemetry event.

* Added telemetry to markdown for error

* Added try catch for markdown preview handler and display error bar

* Updated markdown telemetry to make event names global variable

* Updated Markdown preview to display without vertical scrollbar and removed xml doc to html agility pack.

* Updated parameter name to camel casing and telemetry event name naming.

* Corrected assembbly version for svg renderer

* Removed duplicate function

* Add telemetry for Svg preview handler (#1314)

* Added telemetry events for Svg Preview Handler

* Added unit test in case preview handler throws

* Updated the Error event name

* Remove the not required return statement

* User/lamotile/add read me (#1332)

* add readme

* moved images

* re-added images'

* Fixed gramma

* Update figure number refference

* improve preview handler intergration (#1319)

* improve preview handler intergration

* Fixed typo

* updated typo

* updated enable() function

* updated is enabled()

* re-updated is enabled()

* added this-> key word

* (0.16) - Install preview handler with msix (#1339)

* Removed the registration logic from preview handlers

* Updated the output path

* Added logic to shim the activation of .net assembly

* Updated manifest file

* Fix the allowedsilenttakeover filed in manifest

* Updated the appxmanifest file

* Added AllowSilentDefaultTakeOver in manifest

* Fix returned error code by DllGetClassObject

* Moved the CLSID to a common header file

* Added info about where CLSID needs to be updated

* Added a .reg file for the Keys added in registry.dat

* Added comments for DllGetClassObject

* Svg Preview Handler block external component  (#1368)

* Removed the registration logic from preview handlers

* Updated the output path

* Added logic to shim the activation of .net assembly

* Updated manifest file

* Fix the allowedsilenttakeover filed in manifest

* Updated the appxmanifest file

* Added AllowSilentDefaultTakeOver in manifest

* Fix returned error code by DllGetClassObject

* Moved the CLSID to a common header file

* Added info about where CLSID needs to be updated

* Added a .reg file for the Keys added in registry.dat

* Added comments for DllGetClassObject

* Extended WebBrowserSite for setting flags in DISPID_AMBIENT_DLCONTROL

* Added XML Documenatation

* Removed the logic for deleting image and script element from Svg

* Updated Unit Tests

* Updated typecast of uint

* Forwarded calls to Type.InvokeMember

* Resolve PR Comments

* Adding MSI Installation for Preview Handler (#1436)

* Updated wxs for including dll and registry keys for preview handlers

* Changed the casing for registry key

* Resolve PR Comments

* Added comments for File element

* Call GC on preview unloading (#1456)

* Call GC collect on preview unloading

* Added github issue link

* Update Web browser control for Markdown Previewer (#1464)

* Updated Webbrowser control

* Updated Unit tests

* Disabled Navigation for Svg Previewer

* Fix power preview unit tests (#1508)

* Decoupled registry interaction logic

* Updated File explorer settings

* Updated unit tests for PowerPreview Settings

* Added Asserrtion for Scope of registry key

* Updated the registry value to match with installation registry value

* Sync master settings.cpp

* Merge settings changes from PreviewHandlers

* Remove newline changes added into in example_powertoy\trace.cpp

* Chaned .net framework to 4.7.2

* Updated Csproj files to auto generate Assembly.info files

* Updated msi installer to use version variable for preview handlers assembly

* Removed the signing of Assembly and updated wxs to not include PublicKeyToken

* Updated the Path in Packaginglayout.xml to modules from Gac and the registry hive binary

* Regenerated updated JS and html file

* Resolve PR Comments

* Readded the wprp file

Co-authored-by: Divyansh <divyan@microsoft.com>
Co-authored-by: Divyansh <somm14divi@gmail.com>
Co-authored-by: Lavius Motileng <58791731+laviusmotileng-ms@users.noreply.github.com>
This commit is contained in:
udit3333
2020-03-11 15:53:49 -07:00
committed by GitHub
parent f170cef506
commit 83ce8a2197
107 changed files with 8787 additions and 1850 deletions

View File

@@ -0,0 +1,23 @@
#pragma once
#include <guiddef.h>
// 74619BDA-A66B-451D-864C-A7726F5FE650
// CLSID used in manifest file for Preview Handler.
const CLSID CLSID_SHIMActivateSvgPreviewHandler = { 0x74619BDA, 0xA66B, 0x451D, { 0x86, 0x4C, 0xA7, 0x72, 0x6F, 0x5F, 0xE6, 0x50 } };
// ddee2b8a-6807-48a6-bb20-2338174ff779
// CLSID of the .Net Com Class for Preview Handler. Should be included in the registry.dat file under \Classes\CLSID\{guid}.
// More details here: https://docs.microsoft.com/en-us/dotnet/framework/interop/registering-assemblies-with-com
const CLSID CLSID_SvgPreviewHandler = { 0xddee2b8a, 0x6807, 0x48a6, { 0xbb, 0x20, 0x23, 0x38, 0x17, 0x4f, 0xf7, 0x79 } };
// E0907A95-6F9A-4D1B-A97A-7D9D2648881E
const CLSID CLSID_SHIMActivateMdPreviewHandler = { 0xE0907A95, 0x6F9A, 0x4D1B, { 0xA9, 0x7A, 0x7D, 0x9D, 0x26, 0x48, 0x88, 0x1E } };
// 45769bcc-e8fd-42d0-947e-02beef77a1f5
const CLSID CLSID_MdPreviewHandler = { 0x45769bcc, 0xe8fd, 0x42d0, { 0x94, 0x7e, 0x02, 0xbe, 0xef, 0x77, 0xa1, 0xf5 } };
// Pairs of NativeClsid vs ManagedClsid used for preview handlers.
const std::vector<std::pair<CLSID, CLSID>> NativeToManagedClsid({
{ CLSID_SHIMActivateMdPreviewHandler, CLSID_MdPreviewHandler },
{ CLSID_SHIMActivateSvgPreviewHandler, CLSID_SvgPreviewHandler }
});

View File

@@ -0,0 +1,55 @@
#include "pch.h"
#include <interface/powertoy_module_interface.h>
#include "trace.h"
#include "powerpreview.h"
#include "CLSID.h"
// Logic to shim the Activation of .Net Assembly by calling CoGetClassObject. CLSID's of Preview Handlers should be present in the registry.dat under /Classes/CLSID/{guid}.
// See the existing Preview Handlers registry entry in registry.reg file.
// This is required since MSIX currently not support .Net Assembly for Com Activation for Preview Handlers.
HRESULT CALLBACK DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv)
{
*ppv = NULL;
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
for (auto handler : NativeToManagedClsid)
{
if (handler.first == clsid)
{
hr = CoGetClassObject(handler.second, CLSCTX_INPROC_SERVER, NULL, riid, ppv);
break;
}
}
// In case of failed error code return by CoGetClassObject return CLASS_E_CLASSNOTAVAILABLE to the caller.
if (FAILED(hr))
{
hr = CLASS_E_CLASSNOTAVAILABLE;
*ppv = NULL;
}
return hr;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Trace::RegisterProvider();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
Trace::UnregisterProvider();
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
{
return new PowerPreviewModule();
}

View File

@@ -0,0 +1,3 @@
#include "pch.h"
#pragma comment(lib, "windowsapp")
#pragma comment(lib, "shlwapi.lib")

View File

@@ -0,0 +1,5 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Shlwapi.h>
#include <ProjectTelemetry.h>

View File

@@ -0,0 +1,134 @@
#include "pch.h"
#include <interface/lowlevel_keyboard_event_data.h>
#include <interface/win_hook_event_data.h>
#include <settings_objects.h>
#include <common.h>
#include "powerpreview.h"
#include "trace.h"
#include "settings.h"
#include "resource.h"
// Destroy the powertoy and free memory.
void PowerPreviewModule::destroy()
{
Trace::Destroyed();
for (FileExplorerPreviewSettings* previewHandler : this->m_previewHandlers)
{
if (previewHandler != NULL)
{
delete previewHandler;
}
}
delete this;
}
// Return the display name of the powertoy, this will be cached.
const wchar_t* PowerPreviewModule::get_name()
{
return m_moduleName.c_str();
}
const wchar_t** PowerPreviewModule::get_events()
{
return nullptr;
}
// Return JSON with the configuration options.
bool PowerPreviewModule::get_config(_Out_ wchar_t* buffer, _Out_ int* buffer_size)
{
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
// Create a Settings object.
PowerToysSettings::Settings settings(hinstance, get_name());
// General Settings.
settings.set_description(GET_RESOURCE_STRING(IDS_GENERAL_DESCRIPTION));
settings.set_icon_key(GET_RESOURCE_STRING(IDS_ICON_KEY_NAME));
// Preview Pane: Settings Group Header.
settings.add_header_szLarge(
GET_RESOURCE_STRING(IDS_PRVPANE_FILE_PREV_STTNGS_GROUP_HEADER_ID),
GET_RESOURCE_STRING(IDS_PRVPANE_FILE_PREV_STTNGS_GROUP_DESC),
GET_RESOURCE_STRING(IDS_PRVPANE_FILE_PREV_STTNGS_GROUP_TEXT));
for (FileExplorerPreviewSettings * previewHandler : this->m_previewHandlers)
{
settings.add_bool_toogle(
previewHandler->GetName(),
previewHandler->GetDescription(),
previewHandler->GetState());
}
return settings.serialize_to_buffer(buffer, buffer_size);
}
// Called by the runner to pass the updated settings values as a serialized JSON.
void PowerPreviewModule::set_config(const wchar_t* config)
{
try
{
PowerToysSettings::PowerToyValues values = PowerToysSettings::PowerToyValues::from_json_string(config);
for (FileExplorerPreviewSettings * previewHandler : this->m_previewHandlers)
{
previewHandler->UpdateState(values);
}
values.save_to_settings_file();
}
catch (std::exception const& e)
{
Trace::SetConfigInvalidJSON(e.what());
}
}
// Enable preview handlers.
void PowerPreviewModule::enable()
{
init_settings();
this->m_enabled = true;
}
// Disable all preview handlers.
void PowerPreviewModule::disable()
{
for (FileExplorerPreviewSettings * previewHandler : this->m_previewHandlers)
{
previewHandler->DisablePreview();
}
this->m_enabled = false;
}
// Returns if the powertoys is enabled
bool PowerPreviewModule::is_enabled()
{
return this->m_enabled;
}
// Handle incoming event, data is event-specific
intptr_t PowerPreviewModule::signal_event(const wchar_t* name, intptr_t data)
{
return 0;
}
// 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_name());
// Load settings states.
for (FileExplorerPreviewSettings * previewHandler : this->m_previewHandlers)
{
previewHandler->LoadState(settings);
}
}
catch (std::exception const& e)
{
Trace::InitSetErrorLoadingFile(e.what());
}
}

View File

@@ -0,0 +1,2 @@
EXPORTS
DllGetClassObject PRIVATE

View File

@@ -0,0 +1,59 @@
#include "pch.h"
#include <interface/powertoy_module_interface.h>
#include <common.h>
#include "trace.h"
#include "settings.h"
#include "registry_wrapper.h"
using namespace PowerPreviewSettings;
extern "C" IMAGE_DOS_HEADER __ImageBase;
// Implement the PowerToy Module Interface and all the required methods.
class PowerPreviewModule : public PowertoyModuleIface
{
private:
// The PowerToy state.
bool m_enabled = false;
std::wstring m_moduleName;
std::vector<FileExplorerPreviewSettings *> m_previewHandlers;
public:
PowerPreviewModule() :
m_moduleName(GET_RESOURCE_STRING(IDS_MODULE_NAME)),
m_previewHandlers(
{ // SVG Preview Hanlder settings object.
new FileExplorerPreviewSettings(
false,
GET_RESOURCE_STRING(IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL),
GET_RESOURCE_STRING(IDS_PREVPANE_SVG_SETTINGS_DESCRIPTION),
L"{ddee2b8a-6807-48a6-bb20-2338174ff779}",
GET_RESOURCE_STRING(IDS_PREVPANE_SVG_SETTINGS_DISPLAYNAME),
new RegistryWrapper()),
// MarkDown Preview Handler Settings Object.
new FileExplorerPreviewSettings(
false,
GET_RESOURCE_STRING(IDS_PREVPANE_MD_BOOL_TOGGLE_CONTROLL),
GET_RESOURCE_STRING(IDS_PREVPANE_MD_SETTINGS_DESCRIPTION),
L"{45769bcc-e8fd-42d0-947e-02beef77a1f5}",
GET_RESOURCE_STRING(IDS_PREVPANE_MD_SETTINGS_DISPLAYNAME),
new RegistryWrapper())
})
{
init_settings();
};
virtual void destroy();
virtual const wchar_t* get_name();
virtual const wchar_t** get_events();
virtual bool get_config(_Out_ wchar_t* buffer, _Out_ int* buffer_size);
virtual void set_config(const wchar_t* config);
virtual void enable();
virtual void disable();
virtual bool is_enabled();
virtual void init_settings();
virtual intptr_t signal_event(const wchar_t* name, intptr_t data);
virtual void register_system_menu_helper(PowertoySystemMenuIface* helper) override {}
virtual void signal_system_menu_action(const wchar_t* name) override {}
};

View File

@@ -0,0 +1,78 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE 9, 1
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
STRINGTABLE
BEGIN
IDS_GENERAL_DESCRIPTION L"These settings allow you to manage your Windows File Explorer Addons.";
IDS_MODULE_NAME L"File Explorer Preview";
IDS_ICON_KEY_NAME L"pt-power-preview";
IDS_EXPLR_ICONS_PREV_STTNGS_GROUP_HEADER_ID L"EXPLR_ICONS_PREV_STTNGS_GROUP_HEADER_ID";
IDS_EXPLR_ICONS_PREV_STTNGS_GROUP_DESC L"Settings Group Header Text";
IDS_EXPLR_ICONS_PREV_STTNGS_GROUP_TEXT L"Explorer Icons";
IDS_PRVPANE_FILE_PREV_STTNGS_GROUP_HEADER_ID L"PRVPANE_FILE_PREV_STTNGS_GROUP_HEADER_ID";
IDS_PRVPANE_FILE_PREV_STTNGS_GROUP_DESC L"Settings Group Header Text";
IDS_PRVPANE_FILE_PREV_STTNGS_GROUP_TEXT L"Preview Pane";
IDS_PREVPANE_MD_BOOL_TOGGLE_CONTROLL L"PREVPANE_MD_BOOL_TOGGLE_CONTROLL_ID"
IDS_PREVPANE_MD_SETTINGS_DESCRIPTION L"Markdown Preview Handler"
IDS_PREVPANE_MD_SETTINGS_DISPLAYNAME L"Markdown Preview Handler"
IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL L"IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL"
IDS_PREVPANE_SVG_SETTINGS_DESCRIPTION L"Svg Preview Handler"
IDS_PREVPANE_SVG_SETTINGS_DISPLAYNAME L"SVG Preview Handler"
IDS_EXPLR_SVG_BOOL_TOGGLE_CONTROLL L"EXPLR_SVG_BOOL_TOGGLE_CONTROLL"
IDS_EXPLR_SVG_SETTINGS_DESCRIPTION L"Render SVG images"
END
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{217DF501-135C-4E38-BFC8-99D4821032EA}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>examplepowertoy</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>powerpreview</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\;..\..\..\;..\..\..\..\deps\cpprestsdk\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<ModuleDefinitionFile>powerpreview.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;EXAMPLEPOWERTOY_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>..\..\..\common\Telemetry;..\..\..\common;..\..\common\inc;..\common\Telemetry;..\;..\..\;..\..\..\deps\cpprestsdk\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<ModuleDefinitionFile>powerpreview.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="CLSID.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="registry_wrapper.h" />
<ClInclude Include="registry_wrapper_interface.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="settings.h" />
<ClInclude Include="trace.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pch.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="powerpreview.cpp" />
<ClCompile Include="powerpreview.h" />
<ClCompile Include="registry_wrapper.cpp" />
<ClCompile Include="settings.cpp" />
<ClCompile Include="trace.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="powerpreview.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\common.vcxproj">
<Project>{74485049-c722-400f-abe5-86ac52d929b3}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="powerpreview.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="pch.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="trace.cpp" />
<ClCompile Include="settings.cpp" />
<ClCompile Include="powerpreview.h" />
<ClCompile Include="powerpreview.cpp" />
<ClCompile Include="registry_wrapper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="trace.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="settings.h" />
<ClInclude Include="CLSID.h" />
<ClInclude Include="registry_wrapper.h" />
<ClInclude Include="registry_wrapper_interface.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="powerpreview.rc" />
</ItemGroup>
<ItemGroup>
<None Include="powerpreview.def" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,64 @@
#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, DWORD dwType, 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;
}
}

View File

@@ -0,0 +1,13 @@
#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, DWORD dwType, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);
};
}

View File

@@ -0,0 +1,14 @@
#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, DWORD dwType, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData) = 0;
};

View File

@@ -0,0 +1,32 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by powerpreview.rc
#define IDS_GENERAL_DESCRIPTION 200
#define IDS_MODULE_NAME 201
#define IDS_ICON_KEY_NAME 202
#define IDS_EXPLR_ICONS_PREV_STTNGS_GROUP_HEADER_ID 203
#define IDS_EXPLR_ICONS_PREV_STTNGS_GROUP_DESC 204
#define IDS_EXPLR_ICONS_PREV_STTNGS_GROUP_TEXT 205
#define IDS_PRVPANE_FILE_PREV_STTNGS_GROUP_HEADER_ID 206
#define IDS_PRVPANE_FILE_PREV_STTNGS_GROUP_DESC 207
#define IDS_PRVPANE_FILE_PREV_STTNGS_GROUP_TEXT 208
#define IDS_PREVPANE_MD_BOOL_TOGGLE_CONTROLL 209
#define IDS_PREVPANE_MD_SETTINGS_DESCRIPTION 210
#define IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL 211
#define IDS_PREVPANE_SVG_SETTINGS_DESCRIPTION 212
#define IDS_EXPLR_SVG_BOOL_TOGGLE_CONTROLL 213
#define IDS_EXPLR_SVG_SETTINGS_DESCRIPTION 214
#define IDS_PREVPANE_SVG_SETTINGS_DISPLAYNAME 215
#define IDS_PREVPANE_MD_SETTINGS_DISPLAYNAME 216
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,146 @@
#include "pch.h"
#include <common.h>
#include "settings.h"
#include "trace.h"
#include <iostream>
#include <atlstr.h>
using namespace std;
namespace PowerPreviewSettings
{
extern "C" IMAGE_DOS_HEADER __ImageBase;
// Relative(HKLM/HKCU) sub key path of Preview Handlers list in registry.
static LPCWSTR preview_handlers_subkey = L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers";
// Base Settinngs Class Implementation
FileExplorerPreviewSettings::FileExplorerPreviewSettings(bool enabled, const std::wstring& name, const std::wstring& description, LPCWSTR clsid, const std::wstring& displayname, RegistryWrapperIface * registryWrapper) :
m_isPreviewEnabled(enabled),
m_name(name),
m_description(description),
m_clsid(clsid),
m_displayName(displayname),
m_registryWrapper(registryWrapper)
{
}
FileExplorerPreviewSettings::~FileExplorerPreviewSettings()
{
if (this->m_registryWrapper != NULL)
{
delete this->m_registryWrapper;
}
}
bool FileExplorerPreviewSettings::GetState() const
{
return this->m_isPreviewEnabled;
}
void FileExplorerPreviewSettings::SetState(bool state)
{
this->m_isPreviewEnabled = state;
}
void FileExplorerPreviewSettings::LoadState(PowerToysSettings::PowerToyValues& settings)
{
auto toggle = settings.get_bool_value(this->GetName());
if (toggle != std::nullopt)
{
this->m_isPreviewEnabled = toggle.value();
}
}
void FileExplorerPreviewSettings::UpdateState(PowerToysSettings::PowerToyValues& values)
{
auto toggle = values.get_bool_value(this->GetName());
if (toggle != std::nullopt)
{
if (toggle.value())
{
this->EnablePreview();
}
else
{
this->DisablePreview();
}
}
else
{
Trace::PowerPreviewSettingsUpDateFailed(this->GetName().c_str());
}
}
std::wstring FileExplorerPreviewSettings::GetName() const
{
return this->m_name;
}
void FileExplorerPreviewSettings::SetName(const std::wstring& name)
{
this->m_name = name;
}
std::wstring FileExplorerPreviewSettings::GetDescription() const
{
return this->m_description;
}
void FileExplorerPreviewSettings::SetDescription(const std::wstring& description)
{
this->m_description = description;
}
LPCWSTR FileExplorerPreviewSettings::GetSubKey() const
{
return preview_handlers_subkey;
}
LPCWSTR FileExplorerPreviewSettings::GetCLSID() const
{
return this->m_clsid;
}
std::wstring FileExplorerPreviewSettings::GetDisplayName() const
{
return this->m_displayName;
}
void FileExplorerPreviewSettings::SetDisplayName(const std::wstring& displayName)
{
this->m_displayName = displayName;
}
void FileExplorerPreviewSettings::EnablePreview()
{
// Add registry value to enable preview.
LONG err = this->m_registryWrapper->SetRegistryValue(HKEY_CURRENT_USER, this->GetSubKey(), this->GetCLSID(), REG_SZ, (LPBYTE)this->GetDisplayName().c_str(), (DWORD)(this->GetDisplayName().length() * sizeof(wchar_t)));
if (err == ERROR_SUCCESS)
{
this->SetState(true);
Trace::PreviewHandlerEnabled(true, this->GetDisplayName().c_str());
}
else
{
Trace::PowerPreviewSettingsUpDateFailed(this->GetName().c_str());
}
}
void FileExplorerPreviewSettings::DisablePreview()
{
// Delete the registry key to disable preview.
LONG err = this->m_registryWrapper->DeleteRegistryValue(HKEY_CURRENT_USER, this->GetSubKey(), this->GetCLSID());
if (err == ERROR_SUCCESS)
{
this->SetState(false);
Trace::PreviewHandlerEnabled(false, this->GetDisplayName().c_str());
}
else
{
Trace::PowerPreviewSettingsUpDateFailed(this->GetName().c_str());
}
}
}

View File

@@ -0,0 +1,41 @@
#pragma once
#include <pch.h>
#include <string>
#include "resource.h"
#include <settings_objects.h>
#include "registry_wrapper_interface.h"
namespace PowerPreviewSettings
{
// PowerToy Winodws Explore File Preview Settings.
class FileExplorerPreviewSettings
{
private:
bool m_isPreviewEnabled;
std::wstring m_name;
std::wstring m_description;
std::wstring m_displayName;
RegistryWrapperIface * m_registryWrapper;
LPCWSTR m_clsid;
public:
FileExplorerPreviewSettings(bool enabled, const std::wstring& name, const std::wstring& description, LPCWSTR clsid, const std::wstring& displayname, RegistryWrapperIface* registryWrapper);
~ FileExplorerPreviewSettings();
virtual bool GetState() const;
virtual void SetState(bool state);
virtual void LoadState(PowerToysSettings::PowerToyValues& settings);
virtual void UpdateState(PowerToysSettings::PowerToyValues& values);
virtual std::wstring GetName() const;
virtual void SetName(const std::wstring& name);
virtual std::wstring GetDescription() const;
virtual void SetDescription(const std::wstring& description);
virtual void SetDisplayName(const std::wstring& displayName);
virtual std::wstring GetDisplayName() const;
virtual LPCWSTR GetCLSID() const;
virtual LPCWSTR GetSubKey() const;
virtual void EnablePreview();
virtual void DisablePreview();
};
}

View File

@@ -0,0 +1,86 @@
#include "pch.h"
#include "trace.h"
#include <string>
/*
*
* This file captures the telemetry for the File Explorer Custom Renders project.
* The following telemetry is to be captured for this library:
* (1.) Is the previewer enabled.
* (2.) File rendered per user in 24 hrs per file time (one for MD, one for SVG)
* (3.) Crashes.
*
*/
TRACELOGGING_DEFINE_PROVIDER(
g_hProvider,
"Microsoft.PowerToys",
// {38e8889b-9731-53f5-e901-e8a7c1753074}
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
TraceLoggingOptionProjectTelemetry());
void Trace::RegisterProvider()
{
TraceLoggingRegister(g_hProvider);
}
void Trace::UnregisterProvider()
{
TraceLoggingUnregister(g_hProvider);
}
void Trace::PreviewHandlerEnabled(bool enabled, LPCWSTR previewHandlerName)
{
TraceLoggingWrite(
g_hProvider,
"PowerPreview_TweakUISettings_Enabled",
TraceLoggingWideString(previewHandlerName, "PreviewHanlder_FileType"),
TraceLoggingBoolean(enabled, "Enabled"),
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}
void Trace::PowerPreviewSettingsUpDateFailed(LPCWSTR SettingsName)
{
TraceLoggingWrite(
g_hProvider,
"PowerPreview_TweakUISettings_FailedUpdatingSettings",
TraceLoggingWideString(SettingsName, "ExceptionMessage"),
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}
void Trace::SetConfigInvalidJSON(const char* exceptionMessage)
{
TraceLoggingWrite(
g_hProvider,
"PowerPreview_TweakUISettings_SetConfig__InvalidJSONGiven",
TraceLoggingString(exceptionMessage, "ExceptionMessage"),
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}
void Trace::Destroyed()
{
TraceLoggingWrite(
g_hProvider,
"PowerPreview_TweakUISettings_Destroyed",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}
void Trace::InitSetErrorLoadingFile(const char* exceptionMessage)
{
TraceLoggingWrite(
g_hProvider,
"PowerPreview_TweakUISettings_InitSet__ErrorLoadingFile",
TraceLoggingString(exceptionMessage, "ExceptionMessage"),
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}

View File

@@ -0,0 +1,13 @@
#pragma once
class Trace
{
public:
static void RegisterProvider();
static void UnregisterProvider();
static void SetConfigInvalidJSON(const char* exceptionMessage);
static void InitSetErrorLoadingFile(const char* exceptionMessage);
static void PreviewHandlerEnabled(bool enabled, LPCWSTR previewHandlerName);
static void PowerPreviewSettingsUpDateFailed(LPCWSTR SettingsName);
static void Destroyed();
};