mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 17:42:45 +08:00
Enable PDF files in preview pane (#9088)
## Summary of the Pull Request This PR enables user to preview PDF files in the Explorer preview pane and in Outlook. **What is this about:** Windows does not support out of the box experience for previewing PDF files in the preview pane. Users need to install third-party software like Adobe Acrobat reader. The PdfPreviewHandler module enbales the user to preview PDF files. **How does someone test / validate:** Run the installer, open Explorer and select a PDF file, enable the preview pane. Maybe need to remove third-party PDF software. ## Quality Checklist - [X] **Linked issue:** #3548 - [ ] **Communication:** I've discussed this with core contributors in the issue. - [X] **Tests:** Added/updated and all pass - [X] **Installer:** Added/updated and all pass - [X] **Localization:** All end user facing strings can be localized - [ ] **Docs:** Added/ updated - [x] **Binaries:** Any new files are added to WXS / YML - [ ] No new binaries - [x] YML for signing - [x] WXS for installer
This commit is contained in:
parent
da46b90457
commit
4177708e49
1
.github/actions/spell-check/expect.txt
vendored
1
.github/actions/spell-check/expect.txt
vendored
@ -1527,6 +1527,7 @@ PCWSTR
|
||||
pdb
|
||||
pdbonly
|
||||
pdf
|
||||
pdfpreviewhandler
|
||||
pdo
|
||||
pdto
|
||||
pdtobj
|
||||
|
@ -122,6 +122,8 @@ steps:
|
||||
testAssemblyVer2: |
|
||||
**\UnitTests-SvgThumbnailProvider.dll
|
||||
**\Microsoft.PowerToys.Settings.UI.UnitTests.dll
|
||||
**\UnitTests-MarkdownPreviewHandler.dll
|
||||
**\UnitTests-PdfPreviewHandler.dll
|
||||
**\UnitTests-SvgPreviewHandler.dll
|
||||
**\UnitTests-PreviewHandlerCommon.dll
|
||||
**\PreviewPaneUnitTests.dll
|
||||
|
@ -108,6 +108,8 @@ build:
|
||||
- 'modules\FileExplorerPreview\ManagedTelemetry.dll'
|
||||
- 'modules\FileExplorerPreview\MarkdownPreviewHandler.dll'
|
||||
- 'modules\FileExplorerPreview\MarkdownPreviewHandler.comhost.dll'
|
||||
- 'modules\FileExplorerPreview\PdfPreviewHandler.dll'
|
||||
- 'modules\FileExplorerPreview\PdfPreviewHandler.comhost.dll'
|
||||
- 'modules\FileExplorerPreview\powerpreview.dll'
|
||||
- 'modules\FileExplorerPreview\PreviewHandlerCommon.dll'
|
||||
- 'modules\FileExplorerPreview\SvgPreviewHandler.dll'
|
||||
|
@ -166,7 +166,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PreviewHandlerCommon", "src
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MarkdownPreviewHandler", "src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewHandler.csproj", "{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-MarkdownPreviewHandler", "src\modules\previewpane\PreviewPaneUnitTests\UnitTests-MarkdownPreviewHandler.csproj", "{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-MarkdownPreviewHandler", "src\modules\previewpane\UnitTests-MarkdownPreviewHandler\UnitTests-MarkdownPreviewHandler.csproj", "{A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SvgPreviewHandler", "src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj", "{DA425894-6E13-404F-8DCB-78584EC0557A}"
|
||||
EndProject
|
||||
@ -305,6 +305,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Telemetry", "Telemetry", "{
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Common.UI", "src\common\Microsoft.PowerToys.Common.UI\Microsoft.PowerToys.Common.UI.csproj", "{C3A17DCA-217B-462C-BB0C-BE086AF80081}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfPreviewHandler", "src\modules\previewpane\PdfPreviewHandler\PdfPreviewHandler.csproj", "{69E1EE8D-143A-4060-9129-4658ACF14AAF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-PdfPreviewHandler", "src\modules\previewpane\UnitTests-PdfPreviewHandler\UnitTests-PdfPreviewHandler.csproj", "{ECC20689-002A-4354-95A6-B58DF089C6FF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.Registry", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Registry\Microsoft.PowerToys.Run.Plugin.Registry.csproj", "{4BABF3FE-3451-42FD-873F-3C332E18DCEF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.Registry.UnitTests", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.Registry.UnitTest\Microsoft.PowerToys.Run.Plugin.Registry.UnitTests.csproj", "{0648DF05-5DDA-4BE1-B5F2-584926EBDB65}"
|
||||
@ -796,6 +800,18 @@ Global
|
||||
{C3A17DCA-217B-462C-BB0C-BE086AF80081}.Release|x64.ActiveCfg = Release|x64
|
||||
{C3A17DCA-217B-462C-BB0C-BE086AF80081}.Release|x64.Build.0 = Release|x64
|
||||
{C3A17DCA-217B-462C-BB0C-BE086AF80081}.Release|x86.ActiveCfg = Release|x64
|
||||
{69E1EE8D-143A-4060-9129-4658ACF14AAF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{69E1EE8D-143A-4060-9129-4658ACF14AAF}.Debug|x64.Build.0 = Debug|x64
|
||||
{69E1EE8D-143A-4060-9129-4658ACF14AAF}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{69E1EE8D-143A-4060-9129-4658ACF14AAF}.Release|x64.ActiveCfg = Release|x64
|
||||
{69E1EE8D-143A-4060-9129-4658ACF14AAF}.Release|x64.Build.0 = Release|x64
|
||||
{69E1EE8D-143A-4060-9129-4658ACF14AAF}.Release|x86.ActiveCfg = Release|x64
|
||||
{ECC20689-002A-4354-95A6-B58DF089C6FF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{ECC20689-002A-4354-95A6-B58DF089C6FF}.Debug|x64.Build.0 = Debug|x64
|
||||
{ECC20689-002A-4354-95A6-B58DF089C6FF}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{ECC20689-002A-4354-95A6-B58DF089C6FF}.Release|x64.ActiveCfg = Release|x64
|
||||
{ECC20689-002A-4354-95A6-B58DF089C6FF}.Release|x64.Build.0 = Release|x64
|
||||
{ECC20689-002A-4354-95A6-B58DF089C6FF}.Release|x86.ActiveCfg = Release|x64
|
||||
{4BABF3FE-3451-42FD-873F-3C332E18DCEF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4BABF3FE-3451-42FD-873F-3C332E18DCEF}.Debug|x64.Build.0 = Debug|x64
|
||||
{4BABF3FE-3451-42FD-873F-3C332E18DCEF}.Debug|x86.ActiveCfg = Debug|x64
|
||||
@ -1019,6 +1035,8 @@ Global
|
||||
{B39DC643-4663-475E-B329-03F0C9918D48} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{8F62026A-294B-41C6-8839-87463613F216} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{C3A17DCA-217B-462C-BB0C-BE086AF80081} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||
{69E1EE8D-143A-4060-9129-4658ACF14AAF} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{ECC20689-002A-4354-95A6-B58DF089C6FF} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||
{4BABF3FE-3451-42FD-873F-3C332E18DCEF} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{0648DF05-5DDA-4BE1-B5F2-584926EBDB65} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||
{6ED2F4FC-E122-4CEE-90F1-97E4CCC8BC7A} = {C3081D9A-1586-441A-B5F4-ED815B3719C1}
|
||||
|
@ -79,11 +79,20 @@
|
||||
<desktop2:DesktopPreviewHandler Clsid="74619BDA-A66B-451D-864C-A7726F5FE650"/>
|
||||
</uap3:FileTypeAssociation>
|
||||
</uap:Extension>
|
||||
<uap:Extension Category="windows.fileTypeAssociation">
|
||||
<uap3:FileTypeAssociation Name="pdfpreviewhandler" desktop2:AllowSilentDefaultTakeOver="true">
|
||||
<uap:SupportedFileTypes>
|
||||
<uap:FileType>.pdf</uap:FileType>
|
||||
</uap:SupportedFileTypes>
|
||||
<desktop2:DesktopPreviewHandler Clsid="4F6D533B-4185-43A6-AD75-9B20034B14CA"/>
|
||||
</uap3:FileTypeAssociation>
|
||||
</uap:Extension>
|
||||
<com:Extension Category="windows.comServer">
|
||||
<com:ComServer>
|
||||
<com:SurrogateServer DisplayName="Preview Handler" AppId="E39A92FE-D89A-417B-9B9D-F0B6BD564B36" SystemSurrogate="PreviewHost">
|
||||
<com:Class Id="74619BDA-A66B-451D-864C-A7726F5FE650" Path="modules\powerpreview.dll" ThreadingModel="Both"/>
|
||||
<com:Class Id="E0907A95-6F9A-4D1B-A97A-7D9D2648881E" Path="modules\powerpreview.dll" ThreadingModel="Both"/>
|
||||
<com:Class Id="4F6D533B-4185-43A6-AD75-9B20034B14CA" Path="modules\powerpreview.dll" ThreadingModel="Both"/>
|
||||
</com:SurrogateServer>
|
||||
</com:ComServer>
|
||||
</com:Extension>
|
||||
|
@ -239,7 +239,6 @@
|
||||
</Directory>
|
||||
</Directory>
|
||||
|
||||
|
||||
<!-- KBM -->
|
||||
<Directory Id="KeyboardManagerInstallFolder" Name="$(var.KeyboardManagerProjectName)">
|
||||
<Directory Id="KeyboardManagerEditorInstallFolder" Name="KeyboardManagerEditor" />
|
||||
@ -499,6 +498,19 @@
|
||||
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="Assembly" Value="MarkdownPreviewHandler, Version=$(var.Version).0, Culture=neutral" />
|
||||
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="Class" Value="Microsoft.PowerToys.PreviewHandler.Markdown.MarkdownPreviewHandler" />
|
||||
</RegistryKey>
|
||||
<!-- Registry Key for Class Registration of Pdf Preview Handler -->
|
||||
<RegistryKey Root="HKCR" Key="CLSID\{07665729-6243-4746-95b7-79579308d1b2}">
|
||||
<RegistryValue Type="string" Value="Microsoft.PowerToys.PreviewHandler.Pdf.PdfPreviewHandler" />
|
||||
<RegistryValue Type="string" Name="DisplayName" Value="Pdf Preview Handler" />
|
||||
<RegistryValue Type="string" Name="AppID" Value="{CF142243-F059-45AF-8842-DBBE9783DB14}" />
|
||||
<RegistryValue Type="string" Key="Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" />
|
||||
<RegistryValue Type="string" Key="InprocServer32" Value="[FileExplorerPreviewInstallFolder]PdfPreviewHandler.comhost.dll" />
|
||||
<RegistryValue Type="string" Key="InprocServer32" Name="Assembly" Value="PdfPreviewHandler, Version=$(var.Version).0, Culture=neutral" />
|
||||
<RegistryValue Type="string" Key="InprocServer32" Name="Class" Value="Microsoft.PowerToys.PreviewHandler.Pdf.PdfPreviewHandler" />
|
||||
<RegistryValue Type="string" Key="InprocServer32" Name="ThreadingModel" Value="Both" />
|
||||
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="Assembly" Value="PdfPreviewHandler, Version=$(var.Version).0, Culture=neutral" />
|
||||
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="Class" Value="Microsoft.PowerToys.PreviewHandler.Pdf.PdfPreviewHandler" />
|
||||
</RegistryKey>
|
||||
<!-- Registry Key for AppID registration -->
|
||||
<RegistryKey Root="HKCR" Key="AppID\{CF142243-F059-45AF-8842-DBBE9783DB14}">
|
||||
<RegistryValue Type="expandable" Name="DllSurrogate" Value="%SystemRoot%\system32\prevhost.exe" />
|
||||
@ -511,6 +523,10 @@
|
||||
<RegistryKey Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\PreviewHandlers">
|
||||
<RegistryValue Type="string" Name="{45769bcc-e8fd-42d0-947e-02beef77a1f5}" Value="Markdown Preview Handler" />
|
||||
</RegistryKey>
|
||||
<!-- Add Pdf preview handler to preview handlers list -->
|
||||
<RegistryKey Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\PreviewHandlers">
|
||||
<RegistryValue Type="string" Name="{07665729-6243-4746-95b7-79579308d1b2}" Value="Pdf Preview Handler" />
|
||||
</RegistryKey>
|
||||
<!-- Add file type association for Svg Preview Handler -->
|
||||
<RegistryKey Root="HKCR" Key=".svg\shellex">
|
||||
<RegistryValue Type="string" Key="{8895b1c6-b41f-4c1c-a562-0d564250836f}" Value="{ddee2b8a-6807-48a6-bb20-2338174ff779}" />
|
||||
@ -523,6 +539,10 @@
|
||||
<RegistryKey Root="HKCR" Key=".md\shellex">
|
||||
<RegistryValue Type="string" Key="{8895b1c6-b41f-4c1c-a562-0d564250836f}" Value="{45769bcc-e8fd-42d0-947e-02beef77a1f5}" />
|
||||
</RegistryKey>
|
||||
<!-- Add file type association for Pdf Preview Handler -->
|
||||
<RegistryKey Root="HKCR" Key=".pdf\shellex">
|
||||
<RegistryValue Type="string" Key="{8895b1c6-b41f-4c1c-a562-0d564250836f}" Value="{07665729-6243-4746-95b7-79579308d1b2}" />
|
||||
</RegistryKey>
|
||||
<!-- Update Key to use IE11 for prevhost.exe -->
|
||||
<RegistryKey Root="HKLM" Key="Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION">
|
||||
<RegistryValue Type="integer" Name="prevhost.exe" Value="11000" />
|
||||
@ -784,6 +804,11 @@
|
||||
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\Markdig.Signed.dll" />
|
||||
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\HtmlAgilityPack.dll" />
|
||||
<File Id="FileExplorerPreview_System.IO.Abstractions.dll" Source="$(var.BinX64Dir)modules\FileExplorerPreview\System.IO.Abstractions.dll" />
|
||||
<!-- File to include dll for Pdf Preview Handler -->
|
||||
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\PdfPreviewHandler.dll" />
|
||||
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\PdfPreviewHandler.comhost.dll" />
|
||||
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\PdfPreviewHandler.runtimeconfig.json" />
|
||||
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\PdfPreviewHandler.deps.json" />
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
@ -1022,7 +1047,10 @@
|
||||
<File Id="MarkdownPreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinX64Dir)modules\FileExplorerPreview\$(var.Language)\MarkdownPreviewHandler.resources.dll" />
|
||||
</Component>
|
||||
<Component Id="SVGPreviewHandler_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)FileExplorerPreviewInstallFolder">
|
||||
<File Id="SVGPreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinX64Dir)modules\FileExplorerPreview\$(var.Language)\SvgPreviewHandler.resources.dll" />
|
||||
<File Id="SVGPreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinX64Dir)modules\FileExplorerPreview\$(var.Language)\SvgPreviewHandler.resources.dll" />
|
||||
</Component>
|
||||
<Component Id="PDFPreviewHandler_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)FileExplorerPreviewInstallFolder">
|
||||
<File Id="PDFPreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinX64Dir)modules\FileExplorerPreview\$(var.Language)\PdfPreviewHandler.resources.dll" />
|
||||
</Component>
|
||||
<!-- PowerToys Run aka Launcher plugin resources -->
|
||||
<Component Id="Launcher_Calculator_$(var.IdSafeLanguage)_Component" Directory="Resource$(var.IdSafeLanguage)CalculatorPluginFolder">
|
||||
|
14
src/modules/previewpane/PdfPreviewHandler/LocProject.json
Normal file
14
src/modules/previewpane/PdfPreviewHandler/LocProject.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"Projects": [
|
||||
{
|
||||
"LanguageSet": "Azure_Languages",
|
||||
"LocItems": [
|
||||
{
|
||||
"SourceFile": "src\\modules\\previewpane\\PdfPreviewHandler\\Properties\\Resources.resx",
|
||||
"CopyOption": "LangIDOnName",
|
||||
"OutputPath": "src\\modules\\previewpane\\PdfPreviewHandler\\Properties"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
using Common;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Pdf
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of preview handler for pdf files.
|
||||
/// </summary>
|
||||
[Guid("07665729-6243-4746-95b7-79579308d1b2")]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ComVisible(true)]
|
||||
public class PdfPreviewHandler : StreamBasedPreviewHandler, IDisposable
|
||||
{
|
||||
private PdfPreviewHandlerControl _pdfPreviewHandlerControl;
|
||||
private bool _disposedValue;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfPreviewHandler"/> class.
|
||||
/// </summary>
|
||||
public PdfPreviewHandler()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DoPreview()
|
||||
{
|
||||
_pdfPreviewHandlerControl.DoPreview(Stream);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new Telemetry.Events.PdfFileHandlerLoaded());
|
||||
_pdfPreviewHandlerControl = new PdfPreviewHandlerControl();
|
||||
|
||||
return _pdfPreviewHandlerControl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes objects
|
||||
/// </summary>
|
||||
/// <param name="disposing">Is Disposing</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_pdfPreviewHandlerControl.Dispose();
|
||||
}
|
||||
|
||||
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
|
||||
// TODO: set large fields to null
|
||||
_disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
<PropertyGroup>
|
||||
<Platforms>x64</Platforms>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<AssemblyTitle>PdfPreviewHandler</AssemblyTitle>
|
||||
<AssemblyDescription>PowerToys PdfPreviewHandler</AssemblyDescription>
|
||||
<AssemblyCompany>Microsoft Corp.</AssemblyCompany>
|
||||
<AssemblyCopyright>Copyright (C) 2020 Microsoft Corporation</AssemblyCopyright>
|
||||
<AssemblyProduct>PowerToys</AssemblyProduct>
|
||||
<AssemblyTitle>PdfPreviewHandler</AssemblyTitle>
|
||||
<Company>Microsoft Corp.</Company>
|
||||
<Product>PowerToys</Product>
|
||||
<NeutralLanguage>en-US</NeutralLanguage>
|
||||
<Description>PowerToys PdfPreviewHandler</Description>
|
||||
<Copyright>Copyright (C) 2020 Microsoft Corporation</Copyright>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<DocumentationFile>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\PdfPreviewPaneDocumentation.xml</DocumentationFile>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{69E1EE8D-143A-4060-9129-4658ACF14AAF}</ProjectGuid>
|
||||
<RootNamespace>Microsoft.PowerToys.PreviewHandler.Pdf</RootNamespace>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<EnableComHosting>true</EnableComHosting>
|
||||
<IntermediateOutputPath>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(AssemblyName)\</IntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\..\..\Version.props" />
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\codeAnalysis\GlobalSuppressions.cs" Link="GlobalSuppressions.cs" />
|
||||
<Compile Update="PdfPreviewHandlerControl.cs" />
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.IO.Abstractions" Version="12.2.5" />
|
||||
<PackageReference Include="System.Runtime.WindowsRuntime" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\..\codeAnalysis\StyleCop.json">
|
||||
<Link>StyleCop.json</Link>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
||||
<ProjectReference Include="..\common\PreviewHandlerCommon.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Windows">
|
||||
<HintPath>$(MSBuildProgramFiles32)\Windows Kits\10\UnionMetadata\10.0.17134.0\Windows.winmd</HintPath>
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,299 @@
|
||||
// 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.Drawing;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using Common;
|
||||
using Common.Utilities;
|
||||
using Microsoft.PowerToys.PreviewHandler.Pdf.Properties;
|
||||
using Microsoft.PowerToys.PreviewHandler.Pdf.Telemetry.Events;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
using Windows.Data.Pdf;
|
||||
using Windows.Storage.Streams;
|
||||
using Windows.UI.ViewManagement;
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Pdf
|
||||
{
|
||||
/// <summary>
|
||||
/// Win Form Implementation for Pdf Preview Handler.
|
||||
/// </summary>
|
||||
public class PdfPreviewHandlerControl : FormHandlerControl
|
||||
{
|
||||
/// <summary>
|
||||
/// RichTextBox control to display error message.
|
||||
/// </summary>
|
||||
private RichTextBox _infoBar;
|
||||
|
||||
/// <summary>
|
||||
/// FlowLayoutPanel control to display the image of the pdf.
|
||||
/// </summary>
|
||||
private FlowLayoutPanel _flowLayoutPanel;
|
||||
|
||||
/// <summary>
|
||||
/// Use UISettings to get system colors and scroll bar size.
|
||||
/// </summary>
|
||||
private static UISettings _uISettings = new UISettings();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfPreviewHandlerControl"/> class.
|
||||
/// </summary>
|
||||
public PdfPreviewHandlerControl()
|
||||
{
|
||||
SetBackgroundColor(GetBackgroundColor());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start the preview on the Control.
|
||||
/// </summary>
|
||||
/// <param name="dataSource">Stream reference to access source file.</param>
|
||||
public override void DoPreview<T>(T dataSource)
|
||||
{
|
||||
this.SuspendLayout();
|
||||
|
||||
try
|
||||
{
|
||||
using (var dataStream = new ReadonlyStream(dataSource as IStream))
|
||||
{
|
||||
var memStream = new MemoryStream();
|
||||
dataStream.CopyTo(memStream);
|
||||
memStream.Position = 0;
|
||||
|
||||
try
|
||||
{
|
||||
// AsRandomAccessStream() extension method from System.Runtime.WindowsRuntime
|
||||
var pdf = PdfDocument.LoadFromStreamAsync(memStream.AsRandomAccessStream()).GetAwaiter().GetResult();
|
||||
|
||||
if (pdf.PageCount > 0)
|
||||
{
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
_flowLayoutPanel = new FlowLayoutPanel
|
||||
{
|
||||
AutoScroll = true,
|
||||
AutoSize = true,
|
||||
Dock = DockStyle.Fill,
|
||||
FlowDirection = FlowDirection.TopDown,
|
||||
WrapContents = false,
|
||||
};
|
||||
_flowLayoutPanel.Resize += FlowLayoutPanel_Resize;
|
||||
|
||||
// Only show first 10 pages.
|
||||
for (uint i = 0; i < pdf.PageCount && i < 10; i++)
|
||||
{
|
||||
using (var page = pdf.GetPage(i))
|
||||
{
|
||||
var image = PageToImage(page);
|
||||
|
||||
var picturePanel = new Panel()
|
||||
{
|
||||
Name = "picturePanel",
|
||||
Margin = new Padding(6, 6, 6, 0),
|
||||
Size = CalculateSize(image),
|
||||
BorderStyle = BorderStyle.FixedSingle,
|
||||
};
|
||||
|
||||
var picture = new PictureBox
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Image = image,
|
||||
SizeMode = PictureBoxSizeMode.Zoom,
|
||||
};
|
||||
|
||||
picturePanel.Controls.Add(picture);
|
||||
_flowLayoutPanel.Controls.Add(picturePanel);
|
||||
}
|
||||
}
|
||||
|
||||
if (pdf.PageCount > 10)
|
||||
{
|
||||
var messageBox = new RichTextBox
|
||||
{
|
||||
Name = "messageBox",
|
||||
Text = Resources.PdfMorePagesMessage,
|
||||
BackColor = Color.LightYellow,
|
||||
Dock = DockStyle.Fill,
|
||||
Multiline = true,
|
||||
ReadOnly = true,
|
||||
ScrollBars = RichTextBoxScrollBars.None,
|
||||
BorderStyle = BorderStyle.None,
|
||||
};
|
||||
messageBox.ContentsResized += RTBContentsResized;
|
||||
|
||||
_flowLayoutPanel.Controls.Add(messageBox);
|
||||
}
|
||||
|
||||
Controls.Add(_flowLayoutPanel);
|
||||
});
|
||||
}
|
||||
}
|
||||
#pragma warning disable CA1031 // Password protected files throws an generic Exception
|
||||
catch (Exception ex)
|
||||
#pragma warning restore CA1031
|
||||
{
|
||||
if (ex.Message.Contains("Unable to update the password. The value provided as the current password is incorrect.", StringComparison.Ordinal))
|
||||
{
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
Controls.Clear();
|
||||
_infoBar = GetTextBoxControl(Resources.PdfPasswordProtectedError);
|
||||
Controls.Add(_infoBar);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
memStream.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
PowerToysTelemetry.Log.WriteEvent(new PdfFilePreviewed());
|
||||
}
|
||||
#pragma warning disable CA1031 // Do not catch general exception types
|
||||
catch (Exception ex)
|
||||
#pragma warning restore CA1031 // Do not catch general exception types
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new PdfFilePreviewError { Message = ex.Message });
|
||||
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
Controls.Clear();
|
||||
_infoBar = GetTextBoxControl(Resources.PdfNotPreviewedError);
|
||||
Controls.Add(_infoBar);
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
base.DoPreview(dataSource);
|
||||
}
|
||||
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resize the Panels on FlowLayoutPanel resize based on the size of the image.
|
||||
/// </summary>
|
||||
/// <param name="sender">sender (not used)</param>
|
||||
/// <param name="e">args (not used)</param>
|
||||
private void FlowLayoutPanel_Resize(object sender, EventArgs e)
|
||||
{
|
||||
this.SuspendLayout();
|
||||
_flowLayoutPanel.SuspendLayout();
|
||||
|
||||
foreach (Panel panel in _flowLayoutPanel.Controls.Find("picturePanel", false))
|
||||
{
|
||||
var pictureBox = panel.Controls[0] as PictureBox;
|
||||
var image = pictureBox.Image;
|
||||
|
||||
panel.Size = CalculateSize(image);
|
||||
}
|
||||
|
||||
_flowLayoutPanel.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transform the PdfPage to an Image.
|
||||
/// </summary>
|
||||
/// <param name="page">The page to transform to an Image.</param>
|
||||
/// <returns>An object of type <see cref="Image"/></returns>
|
||||
private Image PageToImage(PdfPage page)
|
||||
{
|
||||
Image imageOfPage;
|
||||
|
||||
using (var stream = new InMemoryRandomAccessStream())
|
||||
{
|
||||
page.RenderToStreamAsync(stream, new PdfPageRenderOptions()
|
||||
{
|
||||
DestinationWidth = (uint)this.ClientSize.Width,
|
||||
}).GetAwaiter().GetResult();
|
||||
|
||||
imageOfPage = Image.FromStream(stream.AsStream());
|
||||
}
|
||||
|
||||
return imageOfPage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the size of the control based on the size of the image/pdf page.
|
||||
/// </summary>
|
||||
/// <param name="pdfImage">Image of pdf page.</param>
|
||||
/// <returns>New size off the panel.</returns>
|
||||
private Size CalculateSize(Image pdfImage)
|
||||
{
|
||||
var hasScrollBar = _flowLayoutPanel.VerticalScroll.Visible;
|
||||
|
||||
// Add 12px margin to the image by making it 12px smaller.
|
||||
int width = this.ClientSize.Width - 12;
|
||||
|
||||
// If the vertical scroll bar is visible, make the image smaller.
|
||||
var scrollBarSizeWidth = (int)_uISettings.ScrollBarSize.Width;
|
||||
if (hasScrollBar && width > scrollBarSizeWidth)
|
||||
{
|
||||
width -= scrollBarSizeWidth;
|
||||
}
|
||||
|
||||
int originalWidth = pdfImage.Width;
|
||||
int originalHeight = pdfImage.Height;
|
||||
float percentWidth = (float)width / originalWidth;
|
||||
|
||||
int newHeight = (int)(originalHeight * percentWidth);
|
||||
|
||||
return new Size(width, newHeight);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the system background color, based on the selected theme.
|
||||
/// </summary>
|
||||
/// <returns>An object of type <see cref="Color"/>.</returns>
|
||||
private static Color GetBackgroundColor()
|
||||
{
|
||||
var systemBackgroundColor = _uISettings.GetColorValue(UIColorType.Background);
|
||||
|
||||
return Color.FromArgb(systemBackgroundColor.A, systemBackgroundColor.R, systemBackgroundColor.G, systemBackgroundColor.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a textbox control.
|
||||
/// </summary>
|
||||
/// <param name="message">Message to be displayed in textbox.</param>
|
||||
/// <returns>An object of type <see cref="RichTextBox"/>.</returns>
|
||||
private RichTextBox GetTextBoxControl(string message)
|
||||
{
|
||||
var textBox = new RichTextBox
|
||||
{
|
||||
Text = message,
|
||||
BackColor = Color.LightYellow,
|
||||
Multiline = true,
|
||||
Dock = DockStyle.Top,
|
||||
ReadOnly = true,
|
||||
ScrollBars = RichTextBoxScrollBars.None,
|
||||
BorderStyle = BorderStyle.None,
|
||||
};
|
||||
textBox.ContentsResized += RTBContentsResized;
|
||||
|
||||
return textBox;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback when RichTextBox is resized.
|
||||
/// </summary>
|
||||
/// <param name="sender">Reference to resized control.</param>
|
||||
/// <param name="e">Provides data for the resize event.</param>
|
||||
private void RTBContentsResized(object sender, ContentsResizedEventArgs e)
|
||||
{
|
||||
var richTextBox = (RichTextBox)sender;
|
||||
|
||||
// Add 5px extra height to the textbox.
|
||||
richTextBox.Height = e.NewRectangle.Height + 5;
|
||||
}
|
||||
}
|
||||
}
|
104
src/modules/previewpane/PdfPreviewHandler/Properties/Resources.Designer.cs
generated
Normal file
104
src/modules/previewpane/PdfPreviewHandler/Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,104 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Pdf.Properties
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if (object.ReferenceEquals(resourceMan, null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.PowerToys.PreviewHandler.Pdf.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This pdf could not be preview due to an internal error..
|
||||
/// </summary>
|
||||
internal static string PdfNotPreviewedError
|
||||
{
|
||||
get
|
||||
{
|
||||
return ResourceManager.GetString("PdfNotPreviewedError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Can't preview pdf. This pdf is password protected..
|
||||
/// </summary>
|
||||
internal static string PdfPasswordProtectedError
|
||||
{
|
||||
get
|
||||
{
|
||||
return ResourceManager.GetString("PdfPasswordProtectedError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This PDF contains more pages, this preview only shows the first 10 pages. Open PDF to view all pages..
|
||||
/// </summary>
|
||||
internal static string PdfMorePagesMessage
|
||||
{
|
||||
get
|
||||
{
|
||||
return ResourceManager.GetString("PdfMorePagesMessage", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="PdfMorePagesMessage" xml:space="preserve">
|
||||
<value>This PDF contains more than 10 pages. Open the document to view all pages.</value>
|
||||
<comment>This text is displayed if PDF has more than 10 pages.</comment>
|
||||
</data>
|
||||
<data name="PdfNotPreviewedError" xml:space="preserve">
|
||||
<value>This PDF could not be previewed due to an internal error.</value>
|
||||
<comment>This text is displayed if PDF fails to preview</comment>
|
||||
</data>
|
||||
<data name="PdfPasswordProtectedError" xml:space="preserve">
|
||||
<value>Can't preview file. This PDF is password protected.</value>
|
||||
<comment>This text is displayed if PDF is password protected.</comment>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,20 @@
|
||||
// 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.Diagnostics.Tracing;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
using Microsoft.PowerToys.Telemetry.Events;
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Pdf.Telemetry.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// A telemetry event that is triggered when a pdf file is viewed in the preview pane.
|
||||
/// </summary>
|
||||
[EventData]
|
||||
public class PdfFileHandlerLoaded : EventBase, IEvent
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
// 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 Microsoft.PowerToys.Telemetry;
|
||||
using Microsoft.PowerToys.Telemetry.Events;
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Pdf.Telemetry.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// A telemetry event that is triggered when an error occurs while attempting to view a markdown file in the preview pane.
|
||||
/// </summary>
|
||||
public class PdfFilePreviewError : EventBase, IEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the error message.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServicePerformance;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
// 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.Diagnostics.Tracing;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
using Microsoft.PowerToys.Telemetry.Events;
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Pdf.Telemetry.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// A telemetry event that is triggered when a markdown file is viewed in the preview pane.
|
||||
/// </summary>
|
||||
[EventData]
|
||||
public class PdfFilePreviewed : EventBase, IEvent
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
|
||||
}
|
||||
}
|
@ -1,2 +1,2 @@
|
||||

|
||||

|
||||
<script>alert("hello")</script>
|
@ -1,2 +1,2 @@
|
||||
## Something
|
||||
## Something
|
||||
<img src="./a.jpg" \>
|
@ -9,7 +9,7 @@ using Microsoft.PowerToys.STATestExtension;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using PreviewHandlerCommon;
|
||||
|
||||
namespace PreviewPaneUnitTests
|
||||
namespace MarkdownPreviewHandlerUnitTests
|
||||
{
|
||||
[STATestClass]
|
||||
public class MarkdownPreviewHandlerTest
|
Binary file not shown.
@ -0,0 +1,89 @@
|
||||
// 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.Drawing;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.PowerToys.PreviewHandler.Pdf;
|
||||
using Microsoft.PowerToys.STATestExtension;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
|
||||
namespace PdfPreviewHandlerUnitTests
|
||||
{
|
||||
[STATestClass]
|
||||
public class PdfPreviewHandlerTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void PdfPreviewHandlerControlAddsControlsToFormWhenDoPreviewIsCalled()
|
||||
{
|
||||
// Arrange
|
||||
using (var pdfPreviewHandlerControl = new PdfPreviewHandlerControl())
|
||||
{
|
||||
// Act
|
||||
var file = File.ReadAllBytes("HelperFiles/sample.pdf");
|
||||
|
||||
pdfPreviewHandlerControl.DoPreview<IStream>(GetMockStream(file));
|
||||
|
||||
var flowLayoutPanel = pdfPreviewHandlerControl.Controls[0] as FlowLayoutPanel;
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, pdfPreviewHandlerControl.Controls.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PdfPreviewHandlerControlShouldAddValidInfoBarIfPdfPreviewThrows()
|
||||
{
|
||||
// Arrange
|
||||
using (var pdfPreviewHandlerControl = new PdfPreviewHandlerControl())
|
||||
{
|
||||
var mockStream = new Mock<IStream>();
|
||||
mockStream
|
||||
.Setup(x => x.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<IntPtr>()))
|
||||
.Throws(new Exception());
|
||||
|
||||
// Act
|
||||
pdfPreviewHandlerControl.DoPreview(mockStream.Object);
|
||||
var textBox = pdfPreviewHandlerControl.Controls[0] as RichTextBox;
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(string.IsNullOrWhiteSpace(textBox.Text));
|
||||
Assert.AreEqual(1, pdfPreviewHandlerControl.Controls.Count);
|
||||
Assert.AreEqual(DockStyle.Top, textBox.Dock);
|
||||
Assert.AreEqual(Color.LightYellow, textBox.BackColor);
|
||||
Assert.IsTrue(textBox.Multiline);
|
||||
Assert.IsTrue(textBox.ReadOnly);
|
||||
Assert.AreEqual(RichTextBoxScrollBars.None, textBox.ScrollBars);
|
||||
Assert.AreEqual(BorderStyle.None, textBox.BorderStyle);
|
||||
}
|
||||
}
|
||||
|
||||
private static IStream GetMockStream(byte[] sourceArray)
|
||||
{
|
||||
var streamMock = new Mock<IStream>();
|
||||
var firstCall = true;
|
||||
streamMock
|
||||
.Setup(x => x.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<IntPtr>()))
|
||||
.Callback<byte[], int, IntPtr>((buffer, countToRead, bytesReadPtr) =>
|
||||
{
|
||||
if (firstCall)
|
||||
{
|
||||
Array.Copy(sourceArray, 0, buffer, 0, sourceArray.Length);
|
||||
Marshal.WriteInt32(bytesReadPtr, sourceArray.Length);
|
||||
firstCall = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Marshal.WriteInt32(bytesReadPtr, 0);
|
||||
}
|
||||
});
|
||||
|
||||
return streamMock.Object;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Platforms>x64</Platforms>
|
||||
<AssemblyTitle>UnitTests-PdfPreviewHandler</AssemblyTitle>
|
||||
<AssemblyDescription>PowerToys UnitTests-PdfPreviewHandler</AssemblyDescription>
|
||||
<AssemblyCompany>Microsoft Corp.</AssemblyCompany>
|
||||
<AssemblyCopyright>Copyright (C) 2020 Microsoft Corp.</AssemblyCopyright>
|
||||
<AssemblyProduct>PowerToys</AssemblyProduct>
|
||||
<AssemblyTitle>UnitTests-PdfPreviewHandler</AssemblyTitle>
|
||||
<Company>Microsoft Corp.</Company>
|
||||
<Product>PowerToys</Product>
|
||||
<NeutralLanguage>en-US</NeutralLanguage>
|
||||
<Description>PowerToys UnitTests-PdfPreviewHandler</Description>
|
||||
<Copyright>Copyright (C) 2020 Microsoft Corp.</Copyright>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{ECC20689-002A-4354-95A6-B58DF089C6FF}</ProjectGuid>
|
||||
<RootNamespace>PreviewPaneUnitTests</RootNamespace>
|
||||
<AssemblyName>PreviewPaneUnitTests</AssemblyName>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||
<IsCodedUITest>False</IsCodedUITest>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\..\..\Version.props" />
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="HelperFiles\dummy-password.pdf" />
|
||||
<None Remove="HelperFiles\dummy.pdf" />
|
||||
<None Remove="HelperFiles\sample.pdf" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Moq" Version="4.14.4" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\common\PreviewHandlerCommon.csproj" />
|
||||
<ProjectReference Include="..\PdfPreviewHandler\PdfPreviewHandler.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\..\..\codeAnalysis\GlobalSuppressions.cs" Link="GlobalSuppressions.cs" />
|
||||
<Content Include="HelperFiles\sample.pdf">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Compile Include="..\STATestClassAttribute.cs" Link="STATestClassAttribute.cs" />
|
||||
<Compile Include="..\STATestMethodAttribute.cs" Link="STATestMethodAttribute.cs" />
|
||||
<AdditionalFiles Include="..\..\..\codeAnalysis\StyleCop.json">
|
||||
<Link>StyleCop.json</Link>
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -16,6 +16,12 @@ const CLSID CLSID_SHIMActivateMdPreviewHandler = { 0xE0907A95, 0x6F9A, 0x4D1B, {
|
||||
// 45769bcc-e8fd-42d0-947e-02beef77a1f5
|
||||
const CLSID CLSID_MdPreviewHandler = { 0x45769bcc, 0xe8fd, 0x42d0, { 0x94, 0x7e, 0x02, 0xbe, 0xef, 0x77, 0xa1, 0xf5 } };
|
||||
|
||||
// 4F6D533B-4185-43A6-AD75-9B20034B14CA
|
||||
const CLSID CLSID_SHIMActivatePdfPreviewHandler = { 0x4f6d533b, 0x4185, 0x43a6, { 0xad, 0x75, 0x9b, 0x20, 0x3, 0x4b, 0x14, 0xca } };
|
||||
|
||||
// 07665729-6243-4746-95b7-79579308d1b2
|
||||
const CLSID CLSID_PdfPreviewHandler = { 0x07665729, 0x6243, 0x4746, { 0x95, 0xb7, 0x79, 0x57, 0x93, 0x08, 0xd1, 0xb2 } };
|
||||
|
||||
// 9C723B8C-4F5C-4147-9DE4-C2808F9AF66B
|
||||
const CLSID CLSID_SHIMActivateSvgThumbnailProvider = { 0x9C723B8C, 0x4F5C, 0x4147, { 0x9D, 0xE4, 0xC2, 0x80, 0x8F, 0x9A, 0xF6, 0x6B } };
|
||||
|
||||
@ -23,8 +29,9 @@ const CLSID CLSID_SHIMActivateSvgThumbnailProvider = { 0x9C723B8C, 0x4F5C, 0x414
|
||||
const CLSID CLSID_SvgThumbnailProvider = { 0x36B27788, 0xA8BB, 0x4698, { 0xA7, 0x56, 0xDF, 0x9F, 0x11, 0xF6, 0x4F, 0x84 } };
|
||||
|
||||
// Pairs of NativeClsid vs ManagedClsid used for preview handlers.
|
||||
const std::vector<std::pair<CLSID, CLSID>> NativeToManagedClsid({
|
||||
const std::vector<std::pair<CLSID, CLSID>> NativeToManagedClsid({
|
||||
{ CLSID_SHIMActivateMdPreviewHandler, CLSID_MdPreviewHandler },
|
||||
{ CLSID_SHIMActivatePdfPreviewHandler, CLSID_PdfPreviewHandler },
|
||||
{ CLSID_SHIMActivateSvgPreviewHandler, CLSID_SvgPreviewHandler },
|
||||
{ CLSID_SHIMActivateSvgThumbnailProvider, CLSID_SvgThumbnailProvider }
|
||||
});
|
@ -167,5 +167,11 @@
|
||||
</data>
|
||||
<data name="FileExplorer_Admin_Restart_Warning_Dont_Show_Again" xml:space="preserve">
|
||||
<value>Don't show again</value>
|
||||
</data>
|
||||
</data>
|
||||
<data name="Prevpane_Pdf_Settings_Description" xml:space="preserve">
|
||||
<value>PDF Previewer</value>
|
||||
</data>
|
||||
<data name="Prevpane_Pdf_Settings_Displayname" xml:space="preserve">
|
||||
<value>PDF Previewer</value>
|
||||
</data>
|
||||
</root>
|
@ -33,6 +33,14 @@ PowerPreviewModule::PowerPreviewModule() :
|
||||
L"Markdown Preview Handler",
|
||||
std::make_unique<RegistryWrapper>()));
|
||||
|
||||
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.emplace_back(std::make_unique<ThumbnailProviderSettings>(
|
||||
true,
|
||||
L"svg-thumbnail-toggle-setting",
|
||||
|
@ -63,6 +63,23 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
}
|
||||
}
|
||||
|
||||
private bool enablePdfPreview = true;
|
||||
|
||||
[JsonPropertyName("pdf-previewer-toggle-setting")]
|
||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||
public bool EnablePdfPreview
|
||||
{
|
||||
get => enablePdfPreview;
|
||||
set
|
||||
{
|
||||
if (value != enablePdfPreview)
|
||||
{
|
||||
LogTelemetryEvent(value);
|
||||
enablePdfPreview = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PowerPreviewProperties()
|
||||
{
|
||||
}
|
||||
|
@ -49,10 +49,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
||||
_svgRenderIsEnabled = Settings.Properties.EnableSvgPreview;
|
||||
_svgThumbnailIsEnabled = Settings.Properties.EnableSvgThumbnail;
|
||||
_mdRenderIsEnabled = Settings.Properties.EnableMdPreview;
|
||||
_pdfRenderIsEnabled = Settings.Properties.EnablePdfPreview;
|
||||
}
|
||||
|
||||
private bool _svgRenderIsEnabled;
|
||||
private bool _mdRenderIsEnabled;
|
||||
private bool _pdfRenderIsEnabled;
|
||||
private bool _svgThumbnailIsEnabled;
|
||||
|
||||
public bool SVGRenderIsEnabled
|
||||
@ -109,6 +111,24 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public bool PDFRenderIsEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return _pdfRenderIsEnabled;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value != _pdfRenderIsEnabled)
|
||||
{
|
||||
_pdfRenderIsEnabled = value;
|
||||
Settings.Properties.EnablePdfPreview = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string GetSettingsSubPath()
|
||||
{
|
||||
return _settingsConfigFileFolder + "\\" + ModuleName;
|
||||
|
@ -57,6 +57,7 @@ namespace ViewModelTests
|
||||
// Verify that the old settings persisted
|
||||
Assert.AreEqual(originalGeneralSettings.IsElevated, viewModel.IsElevated);
|
||||
Assert.AreEqual(originalSettings.Properties.EnableMdPreview, viewModel.MDRenderIsEnabled);
|
||||
Assert.AreEqual(originalSettings.Properties.EnablePdfPreview, viewModel.PDFRenderIsEnabled);
|
||||
Assert.AreEqual(originalSettings.Properties.EnableSvgPreview, viewModel.SVGRenderIsEnabled);
|
||||
Assert.AreEqual(originalSettings.Properties.EnableSvgThumbnail, viewModel.SVGThumbnailIsEnabled);
|
||||
|
||||
@ -118,5 +119,23 @@ namespace ViewModelTests
|
||||
// act
|
||||
viewModel.MDRenderIsEnabled = true;
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PDFRenderIsEnabledShouldPrevHandlerWhenSuccessful()
|
||||
{
|
||||
// Assert
|
||||
Func<string, int> sendMockIPCConfigMSG = msg =>
|
||||
{
|
||||
SndModuleSettings<SndPowerPreviewSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<SndPowerPreviewSettings>>(msg);
|
||||
Assert.IsTrue(snd.PowertoysSetting.FileExplorerPreviewSettings.Properties.EnablePdfPreview);
|
||||
return 0;
|
||||
};
|
||||
|
||||
// arrange
|
||||
PowerPreviewViewModel viewModel = new PowerPreviewViewModel(SettingsRepository<PowerPreviewSettings>.GetInstance(mockPowerPreviewSettingsUtils.Object), SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), sendMockIPCConfigMSG, PowerPreviewSettings.ModuleName);
|
||||
|
||||
// act
|
||||
viewModel.PDFRenderIsEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,6 @@
|
||||
Foreground="{ThemeResource CardPrimaryForegroundBrush}"
|
||||
VerticalAlignment="Center"/>
|
||||
|
||||
|
||||
<StackPanel
|
||||
VerticalAlignment="Center"
|
||||
Grid.Column="1"
|
||||
|
@ -581,6 +581,10 @@
|
||||
<value>Enable SVG (.svg) preview</value>
|
||||
<comment>Do you want this feature on / off</comment>
|
||||
</data>
|
||||
<data name="FileExplorerPreview_ToggleSwitch_Preview_PDF.Header" xml:space="preserve">
|
||||
<value>Enable PDF (.pdf) preview</value>
|
||||
<comment>Do you want this feature on / off</comment>
|
||||
</data>
|
||||
<data name="FileExplorerPreview_ToggleSwitch_SVG_Thumbnail.Header" xml:space="preserve">
|
||||
<value>Enable SVG (.svg) thumbnails</value>
|
||||
<comment>Do you want this feature on / off</comment>
|
||||
|
@ -18,7 +18,6 @@
|
||||
ModuleImageSource="ms-appx:///Assets/Modules/PowerPreview.png">
|
||||
<controls:SettingsPageControl.ModuleContent>
|
||||
|
||||
|
||||
<StackPanel Orientation="Vertical">
|
||||
|
||||
<muxc:InfoBar Severity="Warning"
|
||||
@ -47,10 +46,16 @@
|
||||
IsEnabled="{Binding Mode=OneWay, Path=IsElevated}"/>
|
||||
</controls:Setting.ActionContent>
|
||||
</controls:Setting>
|
||||
|
||||
<controls:Setting x:Uid="FileExplorerPreview_ToggleSwitch_Preview_PDF" Icon="">
|
||||
<controls:Setting.ActionContent>
|
||||
<ToggleSwitch IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.PDFRenderIsEnabled}"
|
||||
IsEnabled="{Binding Mode=OneWay, Path=IsElevated}"/>
|
||||
</controls:Setting.ActionContent>
|
||||
</controls:Setting>
|
||||
</controls:SettingsGroup>
|
||||
|
||||
<controls:SettingsGroup x:Uid="FileExplorerPreview_IconThumbnail_GroupSettings">
|
||||
|
||||
<muxc:InfoBar Severity="Informational"
|
||||
x:Uid="FileExplorerPreview_RebootRequired"
|
||||
IsOpen="True"
|
||||
@ -62,9 +67,8 @@
|
||||
IsEnabled="{Binding Mode=OneWay, Path=IsElevated}"/>
|
||||
</controls:Setting.ActionContent>
|
||||
</controls:Setting>
|
||||
|
||||
|
||||
</controls:SettingsGroup>
|
||||
|
||||
</StackPanel>
|
||||
</controls:SettingsPageControl.ModuleContent>
|
||||
|
||||
|
@ -19,12 +19,14 @@ namespace
|
||||
{ HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\AppUserModelId\\PowerToysRun" },
|
||||
{ HKEY_CLASSES_ROOT, L".svg\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" },
|
||||
{ HKEY_CLASSES_ROOT, L".svg\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}" },
|
||||
{ HKEY_CLASSES_ROOT, L".md\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" }
|
||||
{ HKEY_CLASSES_ROOT, L".md\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" },
|
||||
{ HKEY_CLASSES_ROOT, L".pdf\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" }
|
||||
};
|
||||
|
||||
vector<tuple<HKEY, wstring, wstring>> registryValues = {
|
||||
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers", L"{ddee2b8a-6807-48a6-bb20-2338174ff779}" },
|
||||
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers", L"{45769bcc-e8fd-42d0-947e-02beef77a1f5}" },
|
||||
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers", L"{07665729-6243-4746-95b7-79579308d1b2}" },
|
||||
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", L"prevhost.exe" },
|
||||
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", L"dllhost.exe" }
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user