Self-contained .NET (#22217)

* dotnet sc

* MD preview - C# app

 - working self-contained

* Gcode preview - C# app

* DevFiles preview - C# app

* Fix passing path with spaces as cmd arg and monacocpp proj file

* Pdf preview - C# app

* Svg preview - C# app

* Fix comment

* Gcode thumbnail - C# app

TODO:
	- installer
	- why IThumbnailProvider and IIntializeWithFile doesn't work?

* Pdf thumbnail - C# app

TODO:
        - installer
        - why IThumbnailProvider and IIntializeWithFile doesn't work?

* Pdf thumbnail - C# app

TODO:
        - installer
        - why IThumbnailProvider and IIntializeWithFile doesn't work?

* Fix GcodeThumbnailProviderCpp.vcxproj

* Svg thumbnail - C# app

TODO:
        - installer
        - why IThumbnailProvider and IIntializeWithFile doesn't work?

* Fix Svg tests

* Thumbnail providers - installer

* Self-contained Hosts and FileLocksmith

* Fix hardcoded <RuntimeIdentifier>

* Remove unneeded files

* Try to fix Nuget in PR CI

* Prefix new dlls with PowerToys.
Sign new dlls and exes

* Add new .exe files to ProcessList

* ci: debug by listing all env vars

* ci: try setting variable in the right ci file

* Bring back hardcoded RuntimeIdentifier

* ci: Add comment and remove debug action

* Remove unneeded lib

* [WIP] Platform conditional dotnet files & hardlinks

* Cleanup

* Update expect.txt

* Test fix - ARM installer

* Fix uninstall bug

* Update docs

* Fix failing test

* Add dll details

* Minor cleanup

* Improve resizing

* Add some logs

* Test fix - release build

* Remove InvokeOnControlThread

* Test fix: logger initialization

* Fix arm64 installer

Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
This commit is contained in:
Stefan Markovic 2022-12-14 13:37:23 +01:00 committed by GitHub
parent a2c0febccc
commit 6ac508fb93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
215 changed files with 9060 additions and 2328 deletions

View File

@ -63,6 +63,7 @@ APPIDS
appium
Applets
Applicationcan
applicationconfiguration
applicationframehost
Applist
applog
@ -87,9 +88,11 @@ ARRAYSIZE
arsinh
artanh
Artsakh
asd
asdf
AShortcut
ASingle
Asn
ASSOCCHANGED
ASYNCWINDOWPLACEMENT
ASYNCWINDOWPOS
@ -158,8 +161,8 @@ bpmf
bpp
bricelam
BRIGHTGREEN
Brotli
Browsable
brucelindbloom
bsd
bstr
bti
@ -199,9 +202,8 @@ CHILDACTIVATE
CHILDWINDOW
Choibalsan
chrdavis
chromaticities
Chrzan
CHT
cht
Chukotka
Chuuk
CIELAB
@ -220,6 +222,10 @@ CLIPCHILDREN
Clipperton
CLIPSIBLINGS
clrcall
clrcompression
clretwrc
clrgc
clrjit
Cls
CLSCTX
clsid
@ -234,6 +240,7 @@ CMock
CMONITORS
cmpgt
cmyk
Cng
cnt
Cocklebiddy
coclass
@ -254,13 +261,11 @@ comctl
COMDAT
comdef
comdlg
comhost
cominterop
commandline
COMMANDTITLE
commctrl
Comoros
companding
COMPOSITIONFULL
comsupp
comsuppw
@ -281,6 +286,7 @@ CONTROLL
CONTROLPARENT
Controlz
copiedcolorrepresentation
coreclr
corewebview
cortana
cotaskmem
@ -325,12 +331,10 @@ cwd
cxfksword
CXSMICON
CXVIRTUALSCREEN
cxxopts
cyberrex
CYSMICON
CYVIRTUALSCREEN
cziplib
cziplob
Dac
dacl
damienleroy
@ -346,6 +350,7 @@ davidegiacometti
Dayof
Dbg
Dbghelp
dbgshim
DBLCLKS
DBLEPSILON
DCapture
@ -354,6 +359,7 @@ DCOM
dcommon
dcomp
dcompi
DCompiler
DComposition
DCR
DDevice
@ -388,7 +394,7 @@ DESKTOPABSOLUTEEDITING
DESKTOPABSOLUTEPARSING
desktopshorcutinstalled
desktopwindowxamlsource
DEU
deu
devblogs
devdocs
devenum
@ -476,12 +482,11 @@ ENABLEDPOPUP
endpointvolume
endregion
ENTERSIZEMOVE
ENU
enu
enumerationoptions
EOAC
epicgames
epu
Eqn
ERASEBKGND
EREOF
EResize
@ -490,6 +495,7 @@ ERRORLEVEL
ERRORTITLE
ESettings
esize
esn
esrp
Eswatini
etl
@ -533,7 +539,6 @@ Faroe
FARPROC
fdw
feimage
ffaa
fff
fileapi
FILEEXPLORER
@ -679,6 +684,8 @@ HOMEPATH
homljgmgpmcbpjbnjpfijnhipfkiclkd
HOOKPROC
Hostbackdropbrush
hostfxr
hostpolicy
hotkeycontrol
hotkeys
hotlight
@ -750,6 +757,7 @@ IMAGERESIZEREXT
imageresizerinput
imageresizersettings
imagingdevices
Imc
ime
imeutil
inetcpl
@ -786,17 +794,15 @@ Intelli
interactable
Interlop
INTRESOURCE
Intrinsics
INVALIDARG
invalidoperatioexception
iobjectwithsitesetsite
iolewindowcontextsensitivehelp
ipc
ipcmanager
IPlugin
IPower
ipreview
IPREVIEW
ipreviewhandler
ipreviewhandlertranslateaccelerator
ipreviewhandlervisualssetfont
IProperty
IPublic
@ -824,7 +830,7 @@ jgeosdfsdsgmkedfgdfgdfgbkmhcgcflmi
jjw
jobject
jpe
JPN
jpn
jpnime
JSONOf
Jsons
@ -847,7 +853,6 @@ keyevent
KEYEVENTF
keynum
keyremaps
keystokes
Keytool
keyup
Khakassia
@ -906,6 +911,7 @@ lmcons
LMEM
LMENU
lnk
LOADFROMFILE
LOADLIBRARYASDATAFILE
LOBYTE
LOCALAPPDATA
@ -917,6 +923,7 @@ LOCATIONCHANGE
logconsole
logfile
LOGFONT
LOGFONTW
LOGMSG
logon
LOGPIXELSX
@ -983,6 +990,8 @@ MAPPEDTOSAMEKEY
MAPTOSAMESHORTCUT
MAPVK
Markdig
markdownpreviewhandler
MARKDOWNPREVIEWHANDLERCPP
Markovic
Marquesas
martinchrzan
@ -1015,6 +1024,7 @@ Metadatas
metafile
mfapi
mfc
mfcm
mfidl
mfobjects
mfplat
@ -1074,8 +1084,11 @@ mru
msbuild
msc
msclr
mscordaccore
mscordbi
mscoree
mscorlib
mscorrc
msdata
msedge
MSGFLT
@ -1088,6 +1101,7 @@ MSIXCA
MSLLHOOKSTRUCT
Mso
msp
msquic
msrc
msstore
mst
@ -1137,6 +1151,7 @@ netcpl
netframework
netsetup
netsh
netstandard
Neue
newcolor
newdev
@ -1313,6 +1328,7 @@ pinvoke
pipename
Pitcairn
PKBDLLHOOKSTRUCT
Pkcs
PKEY
plib
PLK
@ -1413,6 +1429,7 @@ QUERYENDSESSION
queryfocus
QUERYOPEN
QUEUESYNC
Quic
Quickime
QUNS
qwertyuiopasdfghjklzxcvbnm
@ -1530,7 +1547,7 @@ runtimeclass
runtimeconfig
runtimeobject
runtimes
RUS
rus
Rutkas
RValue
rvm
@ -1574,7 +1591,6 @@ SETFOCUS
SETFOREGROUND
SETICON
setlocal
Setrect
SETREDRAW
SETTEXT
SETTINGCHANGE
@ -1682,6 +1698,8 @@ srw
srwlock
sse
ssf
Ssl
sss
STACKFRAME
stackoverflow
stackpanel
@ -1799,6 +1817,7 @@ THH
THICKFRAME
THISCOMPONENT
THotkey
thumbcache
TILEDWINDOW
timedate
timediff
@ -1873,7 +1892,7 @@ uniquifier
Uniquifies
unitconverter
unittests
unk
Unk
unknwn
UNLEN
Unmap
@ -2008,7 +2027,6 @@ WINDOWPOSCHANGING
Windowsapp
WINDOWSBUILDNUMBER
Windowscodecs
windowsdesktop
windowssearch
windowssettings
WINDOWSTYLES
@ -2071,6 +2089,7 @@ workspaces
wox
wparam
wpf
wpfgfx
wpftmp
wpr
wprp

View File

@ -46,26 +46,35 @@
"modules\\FancyZones\\PowerToys.FancyZones.exe",
"modules\\FileExplorerPreview\\PowerToys.GcodePreviewHandler.dll",
"modules\\FileExplorerPreview\\PowerToys.GcodePreviewHandler.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.GcodePreviewHandler.exe",
"modules\\FileExplorerPreview\\PowerToys.GcodePreviewHandlerCpp.dll",
"modules\\FileExplorerPreview\\PowerToys.GcodeThumbnailProvider.dll",
"modules\\FileExplorerPreview\\PowerToys.GcodeThumbnailProvider.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.GcodeThumbnailProvider.exe",
"modules\\FileExplorerPreview\\PowerToys.GcodeThumbnailProviderCpp.dll",
"modules\\FileExplorerPreview\\PowerToys.ManagedTelemetry.dll",
"modules\\FileExplorerPreview\\PowerToys.MarkdownPreviewHandler.dll",
"modules\\FileExplorerPreview\\PowerToys.MarkdownPreviewHandler.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.MarkdownPreviewHandler.exe",
"modules\\FileExplorerPreview\\PowerToys.MarkdownPreviewHandlerCpp.dll",
"modules\\FileExplorerPreview\\PowerToys.MonacoPreviewHandler.dll",
"modules\\FileExplorerPreview\\PowerToys.MonacoPreviewHandler.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.MonacoPreviewHandler.exe",
"modules\\FileExplorerPreview\\PowerToys.MonacoPreviewHandlerCpp.dll",
"modules\\FileExplorerPreview\\PowerToys.PdfPreviewHandler.dll",
"modules\\FileExplorerPreview\\PowerToys.PdfPreviewHandler.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.PdfPreviewHandler.exe",
"modules\\FileExplorerPreview\\PowerToys.PdfPreviewHandlerCpp.dll",
"modules\\FileExplorerPreview\\PowerToys.PdfThumbnailProvider.dll",
"modules\\FileExplorerPreview\\PowerToys.PdfThumbnailProvider.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.PdfThumbnailProvider.exe",
"modules\\FileExplorerPreview\\PowerToys.PdfThumbnailProviderCpp.dll",
"modules\\FileExplorerPreview\\PowerToys.powerpreview.dll",
"modules\\FileExplorerPreview\\PowerToys.PreviewHandlerCommon.dll",
"modules\\FileExplorerPreview\\PowerToys.StlThumbnailProvider.dll",
"modules\\FileExplorerPreview\\PowerToys.StlThumbnailProvider.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.StlThumbnailProvider.exe",
"modules\\FileExplorerPreview\\PowerToys.StlThumbnailProviderCpp.dll",
"modules\\FileExplorerPreview\\PowerToys.SvgPreviewHandler.dll",
"modules\\FileExplorerPreview\\PowerToys.SvgPreviewHandler.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.SvgPreviewHandler.exe",
"modules\\FileExplorerPreview\\PowerToys.SvgPreviewHandlerCpp.dll",
"modules\\FileExplorerPreview\\PowerToys.SvgThumbnailProvider.dll",
"modules\\FileExplorerPreview\\PowerToys.SvgThumbnailProvider.comhost.dll",
"modules\\FileExplorerPreview\\PowerToys.SvgThumbnailProvider.exe",
"modules\\FileExplorerPreview\\PowerToys.SvgThumbnailProviderCpp.dll",
"modules\\Hosts\\PowerToys.HostsModuleInterface.dll",
"modules\\Hosts\\PowerToys.Hosts.dll",
@ -238,6 +247,7 @@
"modules\\launcher\\Interop.Microsoft.Office.Interop.OneNote.dll",
"modules\\launcher\\hyjiacan.py4n.dll",
"Settings\\Microsoft.Graphics.Canvas.Interop.dll",
"Settings\\clrcompression.dll",
"Settings\\CommunityToolkit.Labs.WinUI.SettingsControls.dll",
"ColorCode.Core.dll",
"ColorCode.UWP.dll",

View File

@ -9,6 +9,7 @@ jobs:
variables:
BuildConfiguration: ${{ parameters.configuration }}
BuildPlatform: ${{ parameters.platform }}
NUGET_RESTORE_MSBUILD_ARGS: /p:Platform=${{ parameters.platform }} # Required for nuget to work due to self contained
pool:
demands: ImageOverride -equals WinDevVS17-latest
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:

View File

@ -39,6 +39,7 @@ jobs:
${{ config }}_${{ platform }}:
BuildConfiguration: ${{ config }}
BuildPlatform: ${{ platform }}
NUGET_RESTORE_MSBUILD_ARGS: /p:Platform=${{ platform }} # Required for nuget to work due to self contained
displayName: Build
timeoutInMinutes: 120 # Some of the loc stuff adds quite a bit of time.
cancelTimeoutInMinutes: 1

View File

@ -62,7 +62,8 @@ $items | ForEach-Object {
(-not $_.Name.EndsWith("Microsoft.WindowsAppRuntime.Bootstrap.dll")) -and
(-not $_.Name.EndsWith("MRM.dll")) -and
(-not $_.Name.EndsWith("PushNotificationsLongRunningTask.ProxyStub.dll")) -and
(-not $_.Name.EndsWith("WindowsAppSdk.AppxDeploymentExtensions.Desktop.dll"))
(-not $_.Name.EndsWith("WindowsAppSdk.AppxDeploymentExtensions.Desktop.dll")) -and
(-not $_.Name.EndsWith("System.Diagnostics.EventLog.Messages.dll"))
)
{
Write-Host "Version not set: " + $_.FullName

View File

@ -468,6 +468,24 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GPOWrapper", "src\common\GP
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GPOWrapperProjection", "src\common\GPOWrapperProjection\GPOWrapperProjection.csproj", "{00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MarkdownPreviewHandlerCpp", "src\modules\previewpane\MarkdownPreviewHandlerCpp\MarkdownPreviewHandlerCpp.vcxproj", "{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GcodePreviewHandlerCpp", "src\modules\previewpane\GcodePreviewHandlerCpp\GcodePreviewHandlerCpp.vcxproj", "{5A5DD09D-723A-44D3-8F2B-293584C3D731}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MonacoPreviewHandlerCpp", "src\modules\previewpane\MonacoPreviewHandlerCpp\MonacoPreviewHandlerCpp.vcxproj", "{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PdfPreviewHandlerCpp", "src\modules\previewpane\PdfPreviewHandlerCpp\PdfPreviewHandlerCpp.vcxproj", "{54F7C616-FD41-4E62-BFF9-015686914F4D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SvgPreviewHandlerCpp", "src\modules\previewpane\SvgPreviewHandlerCpp\SvgPreviewHandlerCpp.vcxproj", "{143F13E3-D2E3-4D83-B035-356612D99956}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GcodeThumbnailProviderCpp", "src\modules\previewpane\GcodeThumbnailProviderCpp\GcodeThumbnailProviderCpp.vcxproj", "{56CC2F10-6E41-453D-BE16-C593A5E58482}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PdfThumbnailProviderCpp", "src\modules\previewpane\PdfThumbnailProviderCpp\PdfThumbnailProviderCpp.vcxproj", "{CA5518ED-0458-4B09-8F53-4122B9888655}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StlThumbnailProviderCpp", "src\modules\previewpane\StlThumbnailProviderCpp\StlThumbnailProviderCpp.vcxproj", "{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SvgThumbnailProviderCpp", "src\modules\previewpane\SvgThumbnailProviderCpp\SvgThumbnailProviderCpp.vcxproj", "{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
@ -1895,6 +1913,114 @@ Global
{00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Release|x64.Build.0 = Release|x64
{00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Release|x86.ActiveCfg = Release|x64
{00EE9BA6-4E8F-43CA-960D-D4882F0FBB97}.Release|x86.Build.0 = Release|x64
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}.Debug|ARM64.ActiveCfg = Debug|ARM64
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}.Debug|ARM64.Build.0 = Debug|ARM64
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}.Debug|x64.ActiveCfg = Debug|x64
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}.Debug|x64.Build.0 = Debug|x64
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}.Debug|x86.ActiveCfg = Debug|x64
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}.Debug|x86.Build.0 = Debug|x64
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}.Release|ARM64.ActiveCfg = Release|ARM64
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}.Release|ARM64.Build.0 = Release|ARM64
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}.Release|x64.ActiveCfg = Release|x64
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}.Release|x64.Build.0 = Release|x64
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}.Release|x86.ActiveCfg = Release|x64
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545}.Release|x86.Build.0 = Release|x64
{5A5DD09D-723A-44D3-8F2B-293584C3D731}.Debug|ARM64.ActiveCfg = Debug|ARM64
{5A5DD09D-723A-44D3-8F2B-293584C3D731}.Debug|ARM64.Build.0 = Debug|ARM64
{5A5DD09D-723A-44D3-8F2B-293584C3D731}.Debug|x64.ActiveCfg = Debug|x64
{5A5DD09D-723A-44D3-8F2B-293584C3D731}.Debug|x64.Build.0 = Debug|x64
{5A5DD09D-723A-44D3-8F2B-293584C3D731}.Debug|x86.ActiveCfg = Debug|x64
{5A5DD09D-723A-44D3-8F2B-293584C3D731}.Debug|x86.Build.0 = Debug|x64
{5A5DD09D-723A-44D3-8F2B-293584C3D731}.Release|ARM64.ActiveCfg = Release|ARM64
{5A5DD09D-723A-44D3-8F2B-293584C3D731}.Release|ARM64.Build.0 = Release|ARM64
{5A5DD09D-723A-44D3-8F2B-293584C3D731}.Release|x64.ActiveCfg = Release|x64
{5A5DD09D-723A-44D3-8F2B-293584C3D731}.Release|x64.Build.0 = Release|x64
{5A5DD09D-723A-44D3-8F2B-293584C3D731}.Release|x86.ActiveCfg = Release|x64
{5A5DD09D-723A-44D3-8F2B-293584C3D731}.Release|x86.Build.0 = Release|x64
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}.Debug|ARM64.ActiveCfg = Debug|ARM64
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}.Debug|ARM64.Build.0 = Debug|ARM64
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}.Debug|x64.ActiveCfg = Debug|x64
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}.Debug|x64.Build.0 = Debug|x64
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}.Debug|x86.ActiveCfg = Debug|x64
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}.Debug|x86.Build.0 = Debug|x64
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}.Release|ARM64.ActiveCfg = Release|ARM64
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}.Release|ARM64.Build.0 = Release|ARM64
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}.Release|x64.ActiveCfg = Release|x64
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}.Release|x64.Build.0 = Release|x64
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}.Release|x86.ActiveCfg = Release|x64
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9}.Release|x86.Build.0 = Release|x64
{54F7C616-FD41-4E62-BFF9-015686914F4D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{54F7C616-FD41-4E62-BFF9-015686914F4D}.Debug|ARM64.Build.0 = Debug|ARM64
{54F7C616-FD41-4E62-BFF9-015686914F4D}.Debug|x64.ActiveCfg = Debug|x64
{54F7C616-FD41-4E62-BFF9-015686914F4D}.Debug|x64.Build.0 = Debug|x64
{54F7C616-FD41-4E62-BFF9-015686914F4D}.Debug|x86.ActiveCfg = Debug|x64
{54F7C616-FD41-4E62-BFF9-015686914F4D}.Debug|x86.Build.0 = Debug|x64
{54F7C616-FD41-4E62-BFF9-015686914F4D}.Release|ARM64.ActiveCfg = Release|ARM64
{54F7C616-FD41-4E62-BFF9-015686914F4D}.Release|ARM64.Build.0 = Release|ARM64
{54F7C616-FD41-4E62-BFF9-015686914F4D}.Release|x64.ActiveCfg = Release|x64
{54F7C616-FD41-4E62-BFF9-015686914F4D}.Release|x64.Build.0 = Release|x64
{54F7C616-FD41-4E62-BFF9-015686914F4D}.Release|x86.ActiveCfg = Release|x64
{54F7C616-FD41-4E62-BFF9-015686914F4D}.Release|x86.Build.0 = Release|x64
{143F13E3-D2E3-4D83-B035-356612D99956}.Debug|ARM64.ActiveCfg = Debug|ARM64
{143F13E3-D2E3-4D83-B035-356612D99956}.Debug|ARM64.Build.0 = Debug|ARM64
{143F13E3-D2E3-4D83-B035-356612D99956}.Debug|x64.ActiveCfg = Debug|x64
{143F13E3-D2E3-4D83-B035-356612D99956}.Debug|x64.Build.0 = Debug|x64
{143F13E3-D2E3-4D83-B035-356612D99956}.Debug|x86.ActiveCfg = Debug|x64
{143F13E3-D2E3-4D83-B035-356612D99956}.Debug|x86.Build.0 = Debug|x64
{143F13E3-D2E3-4D83-B035-356612D99956}.Release|ARM64.ActiveCfg = Release|ARM64
{143F13E3-D2E3-4D83-B035-356612D99956}.Release|ARM64.Build.0 = Release|ARM64
{143F13E3-D2E3-4D83-B035-356612D99956}.Release|x64.ActiveCfg = Release|x64
{143F13E3-D2E3-4D83-B035-356612D99956}.Release|x64.Build.0 = Release|x64
{143F13E3-D2E3-4D83-B035-356612D99956}.Release|x86.ActiveCfg = Release|x64
{143F13E3-D2E3-4D83-B035-356612D99956}.Release|x86.Build.0 = Release|x64
{56CC2F10-6E41-453D-BE16-C593A5E58482}.Debug|ARM64.ActiveCfg = Debug|ARM64
{56CC2F10-6E41-453D-BE16-C593A5E58482}.Debug|ARM64.Build.0 = Debug|ARM64
{56CC2F10-6E41-453D-BE16-C593A5E58482}.Debug|x64.ActiveCfg = Debug|x64
{56CC2F10-6E41-453D-BE16-C593A5E58482}.Debug|x64.Build.0 = Debug|x64
{56CC2F10-6E41-453D-BE16-C593A5E58482}.Debug|x86.ActiveCfg = Debug|x64
{56CC2F10-6E41-453D-BE16-C593A5E58482}.Debug|x86.Build.0 = Debug|x64
{56CC2F10-6E41-453D-BE16-C593A5E58482}.Release|ARM64.ActiveCfg = Release|ARM64
{56CC2F10-6E41-453D-BE16-C593A5E58482}.Release|ARM64.Build.0 = Release|ARM64
{56CC2F10-6E41-453D-BE16-C593A5E58482}.Release|x64.ActiveCfg = Release|x64
{56CC2F10-6E41-453D-BE16-C593A5E58482}.Release|x64.Build.0 = Release|x64
{56CC2F10-6E41-453D-BE16-C593A5E58482}.Release|x86.ActiveCfg = Release|x64
{56CC2F10-6E41-453D-BE16-C593A5E58482}.Release|x86.Build.0 = Release|x64
{CA5518ED-0458-4B09-8F53-4122B9888655}.Debug|ARM64.ActiveCfg = Debug|ARM64
{CA5518ED-0458-4B09-8F53-4122B9888655}.Debug|ARM64.Build.0 = Debug|ARM64
{CA5518ED-0458-4B09-8F53-4122B9888655}.Debug|x64.ActiveCfg = Debug|x64
{CA5518ED-0458-4B09-8F53-4122B9888655}.Debug|x64.Build.0 = Debug|x64
{CA5518ED-0458-4B09-8F53-4122B9888655}.Debug|x86.ActiveCfg = Debug|x64
{CA5518ED-0458-4B09-8F53-4122B9888655}.Debug|x86.Build.0 = Debug|x64
{CA5518ED-0458-4B09-8F53-4122B9888655}.Release|ARM64.ActiveCfg = Release|ARM64
{CA5518ED-0458-4B09-8F53-4122B9888655}.Release|ARM64.Build.0 = Release|ARM64
{CA5518ED-0458-4B09-8F53-4122B9888655}.Release|x64.ActiveCfg = Release|x64
{CA5518ED-0458-4B09-8F53-4122B9888655}.Release|x64.Build.0 = Release|x64
{CA5518ED-0458-4B09-8F53-4122B9888655}.Release|x86.ActiveCfg = Release|x64
{CA5518ED-0458-4B09-8F53-4122B9888655}.Release|x86.Build.0 = Release|x64
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}.Debug|ARM64.Build.0 = Debug|ARM64
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}.Debug|x64.ActiveCfg = Debug|x64
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}.Debug|x64.Build.0 = Debug|x64
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}.Debug|x86.ActiveCfg = Debug|x64
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}.Debug|x86.Build.0 = Debug|x64
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}.Release|ARM64.ActiveCfg = Release|ARM64
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}.Release|ARM64.Build.0 = Release|ARM64
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}.Release|x64.ActiveCfg = Release|x64
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}.Release|x64.Build.0 = Release|x64
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}.Release|x86.ActiveCfg = Release|x64
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D}.Release|x86.Build.0 = Release|x64
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}.Debug|ARM64.ActiveCfg = Debug|ARM64
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}.Debug|ARM64.Build.0 = Debug|ARM64
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}.Debug|x64.ActiveCfg = Debug|x64
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}.Debug|x64.Build.0 = Debug|x64
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}.Debug|x86.ActiveCfg = Debug|x64
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}.Debug|x86.Build.0 = Debug|x64
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}.Release|ARM64.ActiveCfg = Release|ARM64
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}.Release|ARM64.Build.0 = Release|ARM64
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}.Release|x64.ActiveCfg = Release|x64
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}.Release|x64.Build.0 = Release|x64
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}.Release|x86.ActiveCfg = Release|x64
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA}.Release|x86.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -2056,6 +2182,15 @@ Global
{C604B37E-9D0E-4484-8778-E8B31B0E1B3A} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
{E599C30B-9DC8-4E5A-BF27-93D4CCEDE788} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{00EE9BA6-4E8F-43CA-960D-D4882F0FBB97} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{ED9A1AC6-AEB0-4569-A6E9-E1696182B545} = {2F305555-C296-497E-AC20-5FA1B237996A}
{5A5DD09D-723A-44D3-8F2B-293584C3D731} = {2F305555-C296-497E-AC20-5FA1B237996A}
{B3E869C4-8210-4EBD-A621-FF4C4AFCBFA9} = {2F305555-C296-497E-AC20-5FA1B237996A}
{54F7C616-FD41-4E62-BFF9-015686914F4D} = {2F305555-C296-497E-AC20-5FA1B237996A}
{143F13E3-D2E3-4D83-B035-356612D99956} = {2F305555-C296-497E-AC20-5FA1B237996A}
{56CC2F10-6E41-453D-BE16-C593A5E58482} = {2F305555-C296-497E-AC20-5FA1B237996A}
{CA5518ED-0458-4B09-8F53-4122B9888655} = {2F305555-C296-497E-AC20-5FA1B237996A}
{D6DCC3AE-18C0-488A-B978-BAA9E3CFF09D} = {2F305555-C296-497E-AC20-5FA1B237996A}
{2BBC9E33-21EC-401C-84DA-BB6590A9B2AA} = {2F305555-C296-497E-AC20-5FA1B237996A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}

View File

@ -6,21 +6,13 @@
<?define BinDir="$(var.RepoDir)$(var.Platform)\$(var.Configuration)\" ?>
<?define PowerToysPlatform="x64"?>
<?define Dotnet7DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/5b2fbe00-507e-450e-8b52-43ab052aadf2/79d54c3a19ce3fce314f2367cf4e3b21/windowsdesktop-runtime-7.0.0-win-x64.exe"?>
<?define Dotnet7PayloadSize="57756472"?>
<?define Dotnet7PayloadHash="DB56882D3263C9E533EA7003D018CB7D65F11C10"?>
<?define PlatformProgramFiles="[ProgramFiles64Folder]"?>
<?else?>
<!-- stable WIX 3 doesn't support ARM64, so we build installers as x86 -->
<?define BinDir="$(var.RepoDir)ARM64\$(var.Configuration)\" ?>
<?define PowerToysPlatform="ARM64"?>
<?define Dotnet7DownloadUrl="https://download.visualstudio.microsoft.com/download/pr/bce1b608-3a2a-45e6-ab7b-8c414b9e2c56/74703a44afc5f7550eba824143fc20a7/windowsdesktop-runtime-7.0.0-win-arm64.exe"?>
<?define Dotnet7PayloadSize="53133216"?>
<?define Dotnet7PayloadHash="8A7271390C2538268EFC71F3E49C80017F406C16"?>
<!--TODO: define to ARM64 Program files once it's available-->
<!--TODO: define to ARM64 Program files once it's available-->
<?define PlatformProgramFiles="[ProgramFiles6432Folder]"?>
<?endif?>
@ -41,7 +33,6 @@
SuppressRepair="yes" />
</BootstrapperApplicationRef>
<util:FileSearch Variable="HasDotnet700" Path="$(var.PlatformProgramFiles)dotnet\shared\Microsoft.WindowsDesktop.App\7.0.0\System.Xaml.dll" Result="exists" />
<util:RegistrySearch Variable="HasWebView2PerMachine" Root="HKLM" Key="SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Result="exists" />
<util:RegistrySearch Variable="HasWebView2PerUser" Root="HKCU" Key="Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Result="exists" />
@ -73,26 +64,6 @@
PerMachine="yes"
Vital="no">
</ExePackage>
<ExePackage
DisplayName="Downloading and installing .NET 7 Desktop Runtime"
Name="windowsdesktop-runtime-7.0.0-win-$(var.PowerToysPlatform).exe"
Compressed="no"
Id="DotnetRuntime7"
DetectCondition="HasDotnet700"
DownloadUrl="$(var.Dotnet7DownloadUrl)"
InstallCommand="/install /quiet /norestart"
RepairCommand="/repair /passive /norestart"
Permanent="yes"
PerMachine="yes"
UninstallCommand="/uninstall /quiet /norestart">
<ExitCode Value="1638" Behavior="success"/>
<RemotePayload
Description="Microsoft Windows Desktop Runtime - 7.0.0 ($(var.PowerToysPlatform))"
ProductName="Microsoft Windows Desktop Runtime - 7.0.0 ($(var.PowerToysPlatform))"
Size="$(var.Dotnet7PayloadSize)"
Version="7.0.0.31819"
Hash="$(var.Dotnet7PayloadHash)" />
</ExePackage>
<ExePackage
DisplayName="Installing Microsoft Edge WebView2"
Name="MicrosoftEdgeWebview2Setup.exe"

File diff suppressed because one or more lines are too long

View File

@ -15,6 +15,8 @@
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Management.Deployment.h>
#include "DepsFilesLists.h"
using namespace std;
HINSTANCE DLL_HANDLE = nullptr;
@ -32,56 +34,6 @@ const DWORD USERNAME_LEN = UNLEN + 1; // User Name + '\0'
static const wchar_t* POWERTOYS_EXE_COMPONENT = L"{A2C66D91-3485-4D00-B04D-91844E6B345B}";
static const wchar_t* POWERTOYS_UPGRADE_CODE = L"{42B84BF7-5FBF-473B-9C8B-049DC16F7708}";
const std::vector<std::wstring> winAppSdkFiles = {
L"CoreMessagingXP.dll",
L"DWriteCore.dll",
L"DwmSceneI.dll",
L"MRM.dll",
L"Microsoft.DirectManipulation.dll",
L"Microsoft.InputStateManager.dll",
L"Microsoft.Internal.FrameworkUdk.dll",
L"Microsoft.UI.Composition.OSSupport.dll",
L"Microsoft.UI.Input.dll",
L"Microsoft.UI.Windowing.Core.dll",
L"Microsoft.UI.Xaml.Controls.dll",
L"Microsoft.UI.Xaml.Controls.pri",
L"Microsoft.UI.Xaml.Internal.dll",
L"Microsoft.UI.Xaml.Phone.dll",
L"Microsoft.Web.WebView2.Core.dll",
L"Microsoft.Windows.AppNotifications.Projection.dll",
L"Microsoft.Windows.ApplicationModel.Resources.dll",
L"Microsoft.WindowsAppRuntime.Bootstrap.dll",
L"Microsoft.Windows.PushNotifications.Projection.dll",
L"Microsoft.Windows.System.Projection.dll",
L"Microsoft.WindowsAppRuntime.Insights.Resource.dll",
L"Microsoft.WindowsAppRuntime.Release.Net.dll",
L"Microsoft.WindowsAppRuntime.dll",
L"Microsoft.ui.xaml.dll",
L"Microsoft.ui.xaml.resources.19h1.dll",
L"Microsoft.ui.xaml.resources.common.dll",
L"PushNotificationsLongRunningTask.ProxyStub.dll",
L"WinUIEdit.dll",
L"WindowsAppRuntime.png",
L"WindowsAppSdk.AppxDeploymentExtensions.Desktop.dll",
L"dcompi.dll",
L"dwmcorei.dll",
L"marshal.dll",
L"wuceffectsi.dll" };
const std::vector<std::wstring> powerToysInteropFiles = {
L"concrt140.dll",
L"msvcp140.dll",
L"msvcp140_1.dll",
L"msvcp140_2.dll",
L"msvcp140_atomic_wait.dll",
L"msvcp140_codecvt_ids.dll",
L"PowerToys.Interop.dll",
L"vcamp140.dll",
L"vccorlib140.dll",
L"vcomp140.dll",
L"vcruntime140.dll",
L"vcruntime140_1.dll" };
struct WcaSink : spdlog::sinks::base_sink<std::mutex>
{
virtual void sink_it_(const spdlog::details::log_msg& msg) override
@ -1103,6 +1055,7 @@ const std::wstring PTInteropConsumers[] =
L"modules\\PowerAccent",
L"modules\\FileLocksmith",
L"modules\\Hosts",
L"modules\\FileExplorerPreview",
};
UINT __stdcall CreatePTInteropHardlinksCA(MSIHANDLE hInstall)
@ -1141,6 +1094,87 @@ LExit:
return WcaFinalize(er);
}
UINT __stdcall CreateDotnetRuntimeHardlinksCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
std::wstring installationFolder, dotnetRuntimeFilesSrcDir, colorPickerDir, powerOCRDir, launcherDir, fancyZonesDir,
imageResizerDir, settingsDir, awakeDir, measureToolDir, powerAccentDir, fileExplorerAddOnsDir, hostsDir, fileLocksmithDir;
hr = WcaInitialize(hInstall, "CreateDotnetRuntimeHardlinksCA");
ExitOnFailure(hr, "Failed to initialize");
hr = getInstallFolder(hInstall, installationFolder);
ExitOnFailure(hr, "Failed to get installation folder");
dotnetRuntimeFilesSrcDir = installationFolder + L"dll\\dotnet\\";
colorPickerDir = installationFolder + L"modules\\ColorPicker\\";
powerOCRDir = installationFolder + L"modules\\PowerOCR\\";
launcherDir = installationFolder + L"modules\\launcher\\";
fancyZonesDir = installationFolder + L"modules\\FancyZones\\";
imageResizerDir = installationFolder + L"modules\\ImageResizer\\";
settingsDir = installationFolder + L"Settings\\";
awakeDir = installationFolder + L"modules\\Awake\\";
measureToolDir = installationFolder + L"modules\\MeasureTool\\";
powerAccentDir = installationFolder + L"modules\\PowerAccent\\";
fileExplorerAddOnsDir = installationFolder + L"modules\\FileExplorerPreview\\";
hostsDir = installationFolder + L"modules\\Hosts\\";
fileLocksmithDir = installationFolder + L"modules\\FileLocksmith\\";
for (auto file : dotnetRuntimeFiles)
{
std::error_code ec;
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (colorPickerDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (powerOCRDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (launcherDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (fancyZonesDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (imageResizerDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (settingsDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (awakeDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (measureToolDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (powerAccentDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (fileExplorerAddOnsDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (hostsDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (fileLocksmithDir + file).c_str(), ec);
if (ec.value() != S_OK)
{
std::wstring errorMessage{ L"Error creating hard link for: " };
errorMessage += file;
errorMessage += L", error code: " + std::to_wstring(ec.value());
Logger::error(errorMessage);
er = ERROR_INSTALL_FAILURE;
}
}
for (auto file : dotnetRuntimeWPFFiles)
{
std::error_code ec;
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (awakeDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (colorPickerDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (powerOCRDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (launcherDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (fancyZonesDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (imageResizerDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (powerAccentDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (fileExplorerAddOnsDir + file).c_str(), ec);
std::filesystem::create_hard_link((dotnetRuntimeFilesSrcDir + file).c_str(), (hostsDir + file).c_str(), ec);
if (ec.value() != S_OK)
{
std::wstring errorMessage{ L"Error creating hard link for: " };
errorMessage += file;
errorMessage += L", error code: " + std::to_wstring(ec.value());
Logger::error(errorMessage);
er = ERROR_INSTALL_FAILURE;
}
}
LExit:
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
return WcaFinalize(er);
}
UINT __stdcall DeleteWinAppSDKHardlinksCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
@ -1213,6 +1247,78 @@ LExit:
return WcaFinalize(er);
}
UINT __stdcall DeleteDotnetRuntimeHardlinksCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
std::wstring installationFolder, colorPickerDir, powerOCRDir, launcherDir, fancyZonesDir,
imageResizerDir, settingsDir, awakeDir, measureToolDir, powerAccentDir, fileExplorerAddOnsDir,
hostsDir, fileLocksmithDir;
hr = WcaInitialize(hInstall, "DeleteDotnetRuntimeHardlinksCA");
ExitOnFailure(hr, "Failed to initialize");
hr = getInstallFolder(hInstall, installationFolder);
ExitOnFailure(hr, "Failed to get installation folder");
colorPickerDir = installationFolder + L"modules\\ColorPicker\\";
powerOCRDir = installationFolder + L"modules\\PowerOCR\\";
launcherDir = installationFolder + L"modules\\launcher\\";
fancyZonesDir = installationFolder + L"modules\\FancyZones\\";
imageResizerDir = installationFolder + L"modules\\ImageResizer\\";
settingsDir = installationFolder + L"Settings\\";
awakeDir = installationFolder + L"modules\\Awake\\";
measureToolDir = installationFolder + L"modules\\MeasureTool\\";
powerAccentDir = installationFolder + L"modules\\PowerAccent\\";
fileExplorerAddOnsDir = installationFolder + L"modules\\FileExplorerPreview\\";
hostsDir = installationFolder + L"modules\\Hosts\\";
fileLocksmithDir = installationFolder + L"modules\\FileLocksmith\\";
try
{
for (auto file : dotnetRuntimeFiles)
{
DeleteFile((colorPickerDir + file).c_str());
DeleteFile((powerOCRDir + file).c_str());
DeleteFile((launcherDir + file).c_str());
DeleteFile((fancyZonesDir + file).c_str());
DeleteFile((imageResizerDir + file).c_str());
DeleteFile((settingsDir + file).c_str());
DeleteFile((awakeDir + file).c_str());
DeleteFile((measureToolDir + file).c_str());
DeleteFile((powerAccentDir + file).c_str());
DeleteFile((fileExplorerAddOnsDir + file).c_str());
DeleteFile((hostsDir + file).c_str());
DeleteFile((fileLocksmithDir + file).c_str());
}
for (auto file : dotnetRuntimeWPFFiles)
{
DeleteFile((awakeDir + file).c_str());
DeleteFile((colorPickerDir + file).c_str());
DeleteFile((powerOCRDir + file).c_str());
DeleteFile((launcherDir + file).c_str());
DeleteFile((fancyZonesDir + file).c_str());
DeleteFile((imageResizerDir + file).c_str());
DeleteFile((powerAccentDir + file).c_str());
DeleteFile((fileExplorerAddOnsDir + file).c_str());
DeleteFile((hostsDir + file).c_str());
}
}
catch (std::exception e)
{
std::string errorMessage{ "Exception thrown while trying to delete dotnet runtime hardlinks: " };
errorMessage += e.what();
Logger::error(errorMessage);
er = ERROR_INSTALL_FAILURE;
}
LExit:
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
return WcaFinalize(er);
}
UINT __stdcall TerminateProcessesCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;

View File

@ -7,6 +7,8 @@ EXPORTS
DeleteWinAppSDKHardlinksCA
CreatePTInteropHardlinksCA
DeletePTInteropHardlinksCA
CreateDotnetRuntimeHardlinksCA
DeleteDotnetRuntimeHardlinksCA
DetectPrevInstallPathCA
RemoveScheduledTasksCA
TelemetryLogInstallSuccessCA

View File

@ -0,0 +1,535 @@
#pragma once
#include <vector>
#include <string>
inline const std::vector<std::wstring> winAppSdkFiles = {
L"CoreMessagingXP.dll",
L"DWriteCore.dll",
L"DwmSceneI.dll",
L"MRM.dll",
L"Microsoft.DirectManipulation.dll",
L"Microsoft.InputStateManager.dll",
L"Microsoft.Internal.FrameworkUdk.dll",
L"Microsoft.UI.Composition.OSSupport.dll",
L"Microsoft.UI.Input.dll",
L"Microsoft.UI.Windowing.Core.dll",
L"Microsoft.UI.Xaml.Controls.dll",
L"Microsoft.UI.Xaml.Controls.pri",
L"Microsoft.UI.Xaml.Internal.dll",
L"Microsoft.UI.Xaml.Phone.dll",
L"Microsoft.Web.WebView2.Core.dll",
L"Microsoft.Windows.AppNotifications.Projection.dll",
L"Microsoft.Windows.ApplicationModel.Resources.dll",
L"Microsoft.WindowsAppRuntime.Bootstrap.dll",
L"Microsoft.Windows.PushNotifications.Projection.dll",
L"Microsoft.Windows.System.Projection.dll",
L"Microsoft.WindowsAppRuntime.Insights.Resource.dll",
L"Microsoft.WindowsAppRuntime.Release.Net.dll",
L"Microsoft.WindowsAppRuntime.dll",
L"Microsoft.ui.xaml.dll",
L"Microsoft.ui.xaml.resources.19h1.dll",
L"Microsoft.ui.xaml.resources.common.dll",
L"PushNotificationsLongRunningTask.ProxyStub.dll",
L"WinUIEdit.dll",
L"WindowsAppRuntime.png",
L"WindowsAppSdk.AppxDeploymentExtensions.Desktop.dll",
L"dcompi.dll",
L"dwmcorei.dll",
L"marshal.dll",
L"wuceffectsi.dll"
};
inline const std::vector<std::wstring> powerToysInteropFiles = {
L"concrt140.dll",
L"msvcp140.dll",
L"msvcp140_1.dll",
L"msvcp140_2.dll",
L"msvcp140_atomic_wait.dll",
L"msvcp140_codecvt_ids.dll",
L"PowerToys.Interop.dll",
L"vcamp140.dll",
L"vccorlib140.dll",
L"vcomp140.dll",
L"vcruntime140.dll",
L"vcruntime140_1.dll"
};
#ifdef _M_X64
inline const std::vector<std::wstring> dotnetRuntimeFiles = {
L"clrcompression.dll",
L"clretwrc.dll",
L"clrgc.dll",
L"clrjit.dll",
L"coreclr.dll",
L"hostfxr.dll",
L"hostpolicy.dll",
L"Microsoft.CSharp.dll",
L"Microsoft.DiaSymReader.Native.amd64.dll",
L"Microsoft.VisualBasic.Core.dll",
L"Microsoft.VisualBasic.dll",
L"Microsoft.Win32.Primitives.dll",
L"Microsoft.Win32.Registry.dll",
L"mscordaccore.dll",
L"mscordbi.dll",
L"mscorlib.dll",
L"mscorrc.dll",
L"msquic.dll",
L"netstandard.dll",
L"System.AppContext.dll",
L"System.Buffers.dll",
L"System.CodeDom.dll",
L"System.Collections.Concurrent.dll",
L"System.Collections.dll",
L"System.Collections.Immutable.dll",
L"System.Collections.NonGeneric.dll",
L"System.Collections.Specialized.dll",
L"System.ComponentModel.Annotations.dll",
L"System.ComponentModel.DataAnnotations.dll",
L"System.ComponentModel.dll",
L"System.ComponentModel.EventBasedAsync.dll",
L"System.ComponentModel.Primitives.dll",
L"System.ComponentModel.TypeConverter.dll",
L"System.Configuration.dll",
L"System.Console.dll",
L"System.Core.dll",
L"System.Data.Common.dll",
L"System.Data.DataSetExtensions.dll",
L"System.Data.dll",
L"System.Diagnostics.Contracts.dll",
L"System.Diagnostics.Debug.dll",
L"System.Diagnostics.DiagnosticSource.dll",
L"System.Diagnostics.FileVersionInfo.dll",
L"System.Diagnostics.Process.dll",
L"System.Diagnostics.StackTrace.dll",
L"System.Diagnostics.TextWriterTraceListener.dll",
L"System.Diagnostics.Tools.dll",
L"System.Diagnostics.TraceSource.dll",
L"System.Diagnostics.Tracing.dll",
L"System.dll",
L"System.Drawing.dll",
L"System.Drawing.Primitives.dll",
L"System.Dynamic.Runtime.dll",
L"System.Formats.Asn1.dll",
L"System.Formats.Tar.dll",
L"System.Globalization.Calendars.dll",
L"System.Globalization.dll",
L"System.Globalization.Extensions.dll",
L"System.IO.Compression.Brotli.dll",
L"System.IO.Compression.dll",
L"System.IO.Compression.FileSystem.dll",
L"System.IO.Compression.Native.dll",
L"System.IO.Compression.ZipFile.dll",
L"System.IO.dll",
L"System.IO.FileSystem.AccessControl.dll",
L"System.IO.FileSystem.dll",
L"System.IO.FileSystem.DriveInfo.dll",
L"System.IO.FileSystem.Primitives.dll",
L"System.IO.FileSystem.Watcher.dll",
L"System.IO.IsolatedStorage.dll",
L"System.IO.MemoryMappedFiles.dll",
L"System.IO.Pipes.AccessControl.dll",
L"System.IO.Pipes.dll",
L"System.IO.UnmanagedMemoryStream.dll",
L"System.Linq.dll",
L"System.Linq.Expressions.dll",
L"System.Linq.Parallel.dll",
L"System.Linq.Queryable.dll",
L"System.Memory.dll",
L"System.Net.dll",
L"System.Net.Http.dll",
L"System.Net.Http.Json.dll",
L"System.Net.HttpListener.dll",
L"System.Net.Mail.dll",
L"System.Net.NameResolution.dll",
L"System.Net.NetworkInformation.dll",
L"System.Net.Ping.dll",
L"System.Net.Primitives.dll",
L"System.Net.Quic.dll",
L"System.Net.Requests.dll",
L"System.Net.Security.dll",
L"System.Net.ServicePoint.dll",
L"System.Net.Sockets.dll",
L"System.Net.WebClient.dll",
L"System.Net.WebHeaderCollection.dll",
L"System.Net.WebProxy.dll",
L"System.Net.WebSockets.Client.dll",
L"System.Net.WebSockets.dll",
L"System.Numerics.dll",
L"System.Numerics.Vectors.dll",
L"System.ObjectModel.dll",
L"System.Private.CoreLib.dll",
L"System.Private.DataContractSerialization.dll",
L"System.Private.Uri.dll",
L"System.Private.Xml.dll",
L"System.Private.Xml.Linq.dll",
L"System.Reflection.DispatchProxy.dll",
L"System.Reflection.dll",
L"System.Reflection.Emit.dll",
L"System.Reflection.Emit.ILGeneration.dll",
L"System.Reflection.Emit.Lightweight.dll",
L"System.Reflection.Extensions.dll",
L"System.Reflection.Metadata.dll",
L"System.Reflection.Primitives.dll",
L"System.Reflection.TypeExtensions.dll",
L"System.Resources.Reader.dll",
L"System.Resources.ResourceManager.dll",
L"System.Resources.Writer.dll",
L"System.Runtime.CompilerServices.Unsafe.dll",
L"System.Runtime.CompilerServices.VisualC.dll",
L"System.Runtime.dll",
L"System.Runtime.Extensions.dll",
L"System.Runtime.Handles.dll",
L"System.Runtime.InteropServices.dll",
L"System.Runtime.InteropServices.JavaScript.dll",
L"System.Runtime.InteropServices.RuntimeInformation.dll",
L"System.Runtime.Intrinsics.dll",
L"System.Runtime.Loader.dll",
L"System.Runtime.Numerics.dll",
L"System.Runtime.Serialization.dll",
L"System.Runtime.Serialization.Formatters.dll",
L"System.Runtime.Serialization.Json.dll",
L"System.Runtime.Serialization.Primitives.dll",
L"System.Runtime.Serialization.Xml.dll",
L"System.Security.AccessControl.dll",
L"System.Security.Claims.dll",
L"System.Security.Cryptography.dll",
L"System.Security.Cryptography.Algorithms.dll",
L"System.Security.Cryptography.Cng.dll",
L"System.Security.Cryptography.Csp.dll",
L"System.Security.Cryptography.Encoding.dll",
L"System.Security.Cryptography.OpenSsl.dll",
L"System.Security.Cryptography.Primitives.dll",
L"System.Security.Cryptography.X509Certificates.dll",
L"System.Security.dll",
L"System.Security.Principal.dll",
L"System.Security.Principal.Windows.dll",
L"System.Security.SecureString.dll",
L"System.ServiceModel.Web.dll",
L"System.ServiceProcess.dll",
L"System.Text.Encoding.CodePages.dll",
L"System.Text.Encoding.dll",
L"System.Text.Encoding.Extensions.dll",
L"System.Text.Encodings.Web.dll",
L"System.Text.RegularExpressions.dll",
L"System.Threading.Channels.dll",
L"System.Threading.dll",
L"System.Threading.Overlapped.dll",
L"System.Threading.Tasks.Dataflow.dll",
L"System.Threading.Tasks.dll",
L"System.Threading.Tasks.Extensions.dll",
L"System.Threading.Tasks.Parallel.dll",
L"System.Threading.Thread.dll",
L"System.Threading.ThreadPool.dll",
L"System.Threading.Timer.dll",
L"System.Transactions.dll",
L"System.Transactions.Local.dll",
L"System.ValueTuple.dll",
L"System.Web.dll",
L"System.Web.HttpUtility.dll",
L"System.Windows.dll",
L"System.Xml.dll",
L"System.Xml.Linq.dll",
L"System.Xml.ReaderWriter.dll",
L"System.Xml.Serialization.dll",
L"System.Xml.XDocument.dll",
L"System.Xml.XmlDocument.dll",
L"System.Xml.XmlSerializer.dll",
L"System.Xml.XPath.dll",
L"System.Xml.XPath.XDocument.dll" };
inline const std::vector<std::wstring> dotnetRuntimeWPFFiles = {
L"Accessibility.dll",
L"D3DCompiler_47_cor3.dll",
L"DirectWriteForwarder.dll",
L"Microsoft.VisualBasic.Forms.dll",
L"Microsoft.Win32.Registry.AccessControl.dll",
L"Microsoft.Win32.SystemEvents.dll",
L"PenImc_cor3.dll",
L"PresentationCore.dll",
L"PresentationFramework-SystemCore.dll",
L"PresentationFramework-SystemData.dll",
L"PresentationFramework-SystemDrawing.dll",
L"PresentationFramework-SystemXml.dll",
L"PresentationFramework-SystemXmlLinq.dll",
L"PresentationFramework.Aero.dll",
L"PresentationFramework.Aero2.dll",
L"PresentationFramework.AeroLite.dll",
L"PresentationFramework.Classic.dll",
L"PresentationFramework.dll",
L"PresentationFramework.Luna.dll",
L"PresentationFramework.Royale.dll",
L"PresentationNative_cor3.dll",
L"PresentationUI.dll",
L"ReachFramework.dll",
L"System.Configuration.ConfigurationManager.dll",
L"System.Design.dll",
L"System.Diagnostics.EventLog.dll",
L"System.Diagnostics.EventLog.Messages.dll",
L"System.Diagnostics.PerformanceCounter.dll",
L"System.DirectoryServices.dll",
L"System.Drawing.Common.dll",
L"System.Drawing.Design.dll",
L"System.IO.Packaging.dll",
L"System.Printing.dll",
L"System.Resources.Extensions.dll",
L"System.Security.Cryptography.Pkcs.dll",
L"System.Security.Cryptography.ProtectedData.dll",
L"System.Security.Cryptography.Xml.dll",
L"System.Security.Permissions.dll",
L"System.Threading.AccessControl.dll",
L"System.Windows.Controls.Ribbon.dll",
L"System.Windows.Extensions.dll",
L"System.Windows.Forms.Design.dll",
L"System.Windows.Forms.Design.Editors.dll",
L"System.Windows.Forms.dll",
L"System.Windows.Forms.Primitives.dll",
L"System.Windows.Input.Manipulations.dll",
L"System.Windows.Presentation.dll",
L"System.Xaml.dll",
L"UIAutomationClient.dll",
L"UIAutomationClientSideProviders.dll",
L"UIAutomationProvider.dll",
L"UIAutomationTypes.dll",
L"vcruntime140_cor3.dll",
L"WindowsFormsIntegration.dll",
L"wpfgfx_cor3.dll" };
#else //ARM64
inline const std::vector<std::wstring> dotnetRuntimeFiles = {
L"clretwrc.dll",
L"clrgc.dll",
L"clrjit.dll",
L"coreclr.dll",
L"dbgshim.dll",
L"hostfxr.dll",
L"hostpolicy.dll",
L"Microsoft.CSharp.dll",
L"Microsoft.DiaSymReader.Native.arm64.dll",
L"Microsoft.Graphics.Canvas.dll",
L"Microsoft.VisualBasic.Core.dll",
L"Microsoft.VisualBasic.dll",
L"Microsoft.Win32.Primitives.dll",
L"Microsoft.Win32.Registry.dll",
L"mscordaccore.dll",
L"mscordbi.dll",
L"mscorlib.dll",
L"mscorrc.dll",
L"netstandard.dll",
L"System.AppContext.dll",
L"System.Buffers.dll",
L"System.Collections.Concurrent.dll",
L"System.Collections.dll",
L"System.Collections.Immutable.dll",
L"System.Collections.NonGeneric.dll",
L"System.Collections.Specialized.dll",
L"System.ComponentModel.Annotations.dll",
L"System.ComponentModel.DataAnnotations.dll",
L"System.ComponentModel.dll",
L"System.ComponentModel.EventBasedAsync.dll",
L"System.ComponentModel.Primitives.dll",
L"System.ComponentModel.TypeConverter.dll",
L"System.Configuration.dll",
L"System.Console.dll",
L"System.Core.dll",
L"System.Data.Common.dll",
L"System.Data.DataSetExtensions.dll",
L"System.Data.dll",
L"System.Diagnostics.Contracts.dll",
L"System.Diagnostics.Debug.dll",
L"System.Diagnostics.DiagnosticSource.dll",
L"System.Diagnostics.FileVersionInfo.dll",
L"System.Diagnostics.Process.dll",
L"System.Diagnostics.StackTrace.dll",
L"System.Diagnostics.TextWriterTraceListener.dll",
L"System.Diagnostics.Tools.dll",
L"System.Diagnostics.TraceSource.dll",
L"System.Diagnostics.Tracing.dll",
L"System.dll",
L"System.Drawing.dll",
L"System.Drawing.Primitives.dll",
L"System.Dynamic.Runtime.dll",
L"System.Formats.Asn1.dll",
L"System.Formats.Tar.dll",
L"System.Globalization.Calendars.dll",
L"System.Globalization.dll",
L"System.Globalization.Extensions.dll",
L"System.IO.Compression.Brotli.dll",
L"System.IO.Compression.dll",
L"System.IO.Compression.FileSystem.dll",
L"System.IO.Compression.Native.dll",
L"System.IO.Compression.ZipFile.dll",
L"System.IO.dll",
L"System.IO.FileSystem.AccessControl.dll",
L"System.IO.FileSystem.dll",
L"System.IO.FileSystem.DriveInfo.dll",
L"System.IO.FileSystem.Primitives.dll",
L"System.IO.FileSystem.Watcher.dll",
L"System.IO.IsolatedStorage.dll",
L"System.IO.MemoryMappedFiles.dll",
L"System.IO.Pipes.AccessControl.dll",
L"System.IO.Pipes.dll",
L"System.IO.UnmanagedMemoryStream.dll",
L"System.Linq.dll",
L"System.Linq.Expressions.dll",
L"System.Linq.Parallel.dll",
L"System.Linq.Queryable.dll",
L"System.Memory.dll",
L"System.Net.dll",
L"System.Net.Http.dll",
L"System.Net.Http.Json.dll",
L"System.Net.HttpListener.dll",
L"System.Net.Mail.dll",
L"System.Net.NameResolution.dll",
L"System.Net.NetworkInformation.dll",
L"System.Net.Ping.dll",
L"System.Net.Primitives.dll",
L"System.Net.Quic.dll",
L"System.Net.Requests.dll",
L"System.Net.Security.dll",
L"System.Net.ServicePoint.dll",
L"System.Net.Sockets.dll",
L"System.Net.WebClient.dll",
L"System.Net.WebHeaderCollection.dll",
L"System.Net.WebProxy.dll",
L"System.Net.WebSockets.Client.dll",
L"System.Net.WebSockets.dll",
L"System.Numerics.dll",
L"System.Numerics.Vectors.dll",
L"System.ObjectModel.dll",
L"System.Private.CoreLib.dll",
L"System.Private.DataContractSerialization.dll",
L"System.Private.Uri.dll",
L"System.Private.Xml.dll",
L"System.Private.Xml.Linq.dll",
L"System.Reflection.DispatchProxy.dll",
L"System.Reflection.dll",
L"System.Reflection.Emit.dll",
L"System.Reflection.Emit.ILGeneration.dll",
L"System.Reflection.Emit.Lightweight.dll",
L"System.Reflection.Extensions.dll",
L"System.Reflection.Metadata.dll",
L"System.Reflection.Primitives.dll",
L"System.Reflection.TypeExtensions.dll",
L"System.Resources.Reader.dll",
L"System.Resources.ResourceManager.dll",
L"System.Resources.Writer.dll",
L"System.Runtime.CompilerServices.Unsafe.dll",
L"System.Runtime.CompilerServices.VisualC.dll",
L"System.Runtime.dll",
L"System.Runtime.Extensions.dll",
L"System.Runtime.Handles.dll",
L"System.Runtime.InteropServices.dll",
L"System.Runtime.InteropServices.JavaScript.dll",
L"System.Runtime.InteropServices.RuntimeInformation.dll",
L"System.Runtime.Intrinsics.dll",
L"System.Runtime.Loader.dll",
L"System.Runtime.Numerics.dll",
L"System.Runtime.Serialization.dll",
L"System.Runtime.Serialization.Formatters.dll",
L"System.Runtime.Serialization.Json.dll",
L"System.Runtime.Serialization.Primitives.dll",
L"System.Runtime.Serialization.Xml.dll",
L"System.Security.AccessControl.dll",
L"System.Security.Claims.dll",
L"System.Security.Cryptography.dll",
L"System.Security.Cryptography.Algorithms.dll",
L"System.Security.Cryptography.Cng.dll",
L"System.Security.Cryptography.Csp.dll",
L"System.Security.Cryptography.Encoding.dll",
L"System.Security.Cryptography.OpenSsl.dll",
L"System.Security.Cryptography.Primitives.dll",
L"System.Security.Cryptography.X509Certificates.dll",
L"System.Security.dll",
L"System.Security.Principal.dll",
L"System.Security.Principal.Windows.dll",
L"System.Security.SecureString.dll",
L"System.ServiceModel.Web.dll",
L"System.ServiceProcess.dll",
L"System.Text.Encoding.CodePages.dll",
L"System.Text.Encoding.dll",
L"System.Text.Encoding.Extensions.dll",
L"System.Text.Encodings.Web.dll",
L"System.Text.Json.dll",
L"System.Text.RegularExpressions.dll",
L"System.Threading.Channels.dll",
L"System.Threading.dll",
L"System.Threading.Overlapped.dll",
L"System.Threading.Tasks.Dataflow.dll",
L"System.Threading.Tasks.dll",
L"System.Threading.Tasks.Extensions.dll",
L"System.Threading.Tasks.Parallel.dll",
L"System.Threading.Thread.dll",
L"System.Threading.ThreadPool.dll",
L"System.Threading.Timer.dll",
L"System.Transactions.dll",
L"System.Transactions.Local.dll",
L"System.ValueTuple.dll",
L"System.Web.dll",
L"System.Web.HttpUtility.dll",
L"System.Windows.dll",
L"System.Xml.dll",
L"System.Xml.Linq.dll",
L"System.Xml.ReaderWriter.dll",
L"System.Xml.Serialization.dll",
L"System.Xml.XDocument.dll",
L"System.Xml.XmlDocument.dll",
L"System.Xml.XmlSerializer.dll",
L"System.Xml.XPath.dll",
L"System.Xml.XPath.XDocument.dll" };
inline const std::vector<std::wstring> dotnetRuntimeWPFFiles = {
L"Accessibility.dll",
L"DirectWriteForwarder.dll",
L"Microsoft.VisualBasic.Forms.dll",
L"Microsoft.Win32.Registry.AccessControl.dll",
L"Microsoft.Win32.SystemEvents.dll",
L"PenImc_cor3.dll",
L"PresentationCore.dll",
L"PresentationFramework-SystemCore.dll",
L"PresentationFramework-SystemData.dll",
L"PresentationFramework-SystemDrawing.dll",
L"PresentationFramework-SystemXml.dll",
L"PresentationFramework-SystemXmlLinq.dll",
L"PresentationFramework.Aero.dll",
L"PresentationFramework.Aero2.dll",
L"PresentationFramework.AeroLite.dll",
L"PresentationFramework.Classic.dll",
L"PresentationFramework.dll",
L"PresentationFramework.Luna.dll",
L"PresentationFramework.Royale.dll",
L"PresentationNative_cor3.dll",
L"PresentationUI.dll",
L"ReachFramework.dll",
L"System.CodeDom.dll",
L"System.Configuration.ConfigurationManager.dll",
L"System.Design.dll",
L"System.Diagnostics.EventLog.dll",
L"System.Diagnostics.EventLog.Messages.dll",
L"System.Diagnostics.PerformanceCounter.dll",
L"System.DirectoryServices.dll",
L"System.Drawing.Common.dll",
L"System.Drawing.Design.dll",
L"System.IO.Packaging.dll",
L"System.Security.Cryptography.Pkcs.dll",
L"System.Security.Cryptography.ProtectedData.dll",
L"System.Security.Cryptography.Xml.dll",
L"System.Security.Permissions.dll",
L"System.Threading.AccessControl.dll",
L"System.Windows.Controls.Ribbon.dll",
L"System.Windows.Extensions.dll",
L"System.Windows.Forms.Design.dll",
L"System.Windows.Forms.Design.Editors.dll",
L"System.Windows.Forms.dll",
L"System.Windows.Forms.Primitives.dll",
L"System.Windows.Input.Manipulations.dll",
L"System.Windows.Presentation.dll",
L"System.Xaml.dll",
L"UIAutomationClient.dll",
L"UIAutomationClientSideProviders.dll",
L"UIAutomationProvider.dll",
L"UIAutomationTypes.dll",
L"vcruntime140_cor3.dll",
L"WindowsFormsIntegration.dll",
L"wpfgfx_cor3.dll"
};
#endif

View File

@ -109,6 +109,7 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="DepsFilesLists.h" />
<ClInclude Include="RcResource.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="stdafx.h" />

View File

@ -14,6 +14,7 @@
</ClInclude>
<ClInclude Include="resource.h" />
<ClInclude Include="RcResource.h" />
<ClInclude Include="DepsFilesLists.h" />
</ItemGroup>
<ItemGroup>
<None Include="CustomAction.def" />

View File

@ -207,5 +207,24 @@ public
return gcnew String(CommonSharedConstants::POWERACCENT_EXIT_EVENT);
}
static String ^ GcodePreviewResizeEvent() {
return gcnew String(CommonSharedConstants::GCODE_PREVIEW_RESIZE_EVENT);
}
static String ^ DevFilesPreviewResizeEvent() {
return gcnew String(CommonSharedConstants::DEV_FILES_PREVIEW_RESIZE_EVENT);
}
static String ^ MarkdownPreviewResizeEvent() {
return gcnew String(CommonSharedConstants::MARKDOWN_PREVIEW_RESIZE_EVENT);
}
static String ^ PdfPreviewResizeEvent() {
return gcnew String(CommonSharedConstants::PDF_PREVIEW_RESIZE_EVENT);
}
static String ^ SvgPreviewResizeEvent() {
return gcnew String(CommonSharedConstants::SVG_PREVIEW_RESIZE_EVENT);
}
};
}

View File

@ -44,6 +44,21 @@ namespace CommonSharedConstants
// Path to the event used by PowerOCR
const wchar_t SHOW_POWEROCR_SHARED_EVENT[] = L"Local\\PowerOCREvent-dc864e06-e1af-4ecc-9078-f98bee745e3a";
// Path to the event used by GcodePreviewHandler
const wchar_t GCODE_PREVIEW_RESIZE_EVENT[] = L"Local\\PowerToysGcodePreviewResizeEvent-6ff1f9bd-ccbd-4b24-a79f-40a34fb0317d";
// Path to the event used by DevFilesPreviewHandler
const wchar_t DEV_FILES_PREVIEW_RESIZE_EVENT[] = L"Local\\PowerToysDevFilesPreviewResizeEvent-5707a22c-2cac-4ea2-82f0-27c03ef0b5f3";
// Path to the event used by MarkdownPreviewHandler
const wchar_t MARKDOWN_PREVIEW_RESIZE_EVENT[] = L"Local\\PowerToysMarkdownPreviewResizeEvent-54c9ab69-11f3-49e9-a98f-53221cfef3ec";
// Path to the event used by MarkdownPreviewHandler
const wchar_t PDF_PREVIEW_RESIZE_EVENT[] = L"Local\\PowerToysPdfPreviewResizeEvent-5a2f162a-f728-45fe-8bda-ef3d5e434ce7";
// Path to the event used by MarkdownPreviewHandler
const wchar_t SVG_PREVIEW_RESIZE_EVENT[] = L"Local\\PowerToysSvgPreviewResizeEvent-0701a4fc-d5a1-4ee7-b885-f83982c62a0d";
// Max DWORD for key code to disable keys.
const DWORD VK_DISABLED = 0x100;
}

View File

@ -58,18 +58,24 @@ bool Logger::wasLogFailedShown()
void Logger::init(std::string loggerName, std::wstring logFilePath, std::wstring_view logSettingsPath)
{
auto logLevel = getLogLevel(logSettingsPath);
bool newLoggerCreated = false;
try
{
auto sink = make_shared<daily_file_sink_mt>(logFilePath, 0, 0, false, LogSettings::retention);
if (IsDebuggerPresent())
logger = spdlog::get(loggerName);
if (logger == nullptr)
{
auto msvc_sink = make_shared<msvc_sink_mt>();
msvc_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%f] [%n] [t-%t] [%l] %v");
logger = make_shared<spdlog::logger>(loggerName, sinks_init_list{ sink, msvc_sink });
}
else
{
logger = make_shared<spdlog::logger>(loggerName, sink);
auto sink = make_shared<daily_file_sink_mt>(logFilePath, 0, 0, false, LogSettings::retention);
if (IsDebuggerPresent())
{
auto msvc_sink = make_shared<msvc_sink_mt>();
msvc_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%f] [%n] [t-%t] [%l] %v");
logger = make_shared<spdlog::logger>(loggerName, sinks_init_list{ sink, msvc_sink });
}
else
{
logger = make_shared<spdlog::logger>(loggerName, sink);
}
newLoggerCreated = true;
}
}
catch (...)
@ -89,10 +95,14 @@ void Logger::init(std::string loggerName, std::wstring logFilePath, std::wstring
return;
}
logger->set_level(logLevel);
logger->set_pattern("[%Y-%m-%d %H:%M:%S.%f] [p-%P] [t-%t] [%l] %v");
logger->flush_on(logLevel); // Auto flush on every log message.
spdlog::register_logger(logger);
if (newLoggerCreated)
{
logger->set_level(logLevel);
logger->set_pattern("[%Y-%m-%d %H:%M:%S.%f] [p-%P] [t-%t] [%l] %v");
logger->flush_on(logLevel); // Auto flush on every log message.
spdlog::register_logger(logger);
}
logger->info("{} logger is initialized", loggerName);
}

View File

@ -15,6 +15,24 @@ struct LogSettings
inline const static std::wstring updateLogPath = L"UpdateLogs\\update-log.txt";
inline const static std::string fileExplorerLoggerName = "FileExplorer";
inline const static std::wstring fileExplorerLogPath = L"Logs\\file-explorer-log.txt";
inline const static std::string gcodePrevLoggerName = "GcodePrevHandler";
inline const static std::wstring gcodePrevLogPath = L"logs\\FileExplorer_localLow\\GcodePreviewHandler\\gcode-prev-handler-log.txt";
inline const static std::string gcodeThumbLoggerName = "GcodeThumbnailProvider";
inline const static std::wstring gcodeThumbLogPath = L"logs\\FileExplorer_localLow\\GcodeThumbnailProvider\\gcode-thumbnail-provider-log.txt";
inline const static std::string mdPrevLoggerName = "MDPrevHandler";
inline const static std::wstring mdPrevLogPath = L"logs\\FileExplorer_localLow\\MDPrevHandler\\md-prev-handler-log.txt";
inline const static std::string monacoPrevLoggerName = "MonacoPrevHandler";
inline const static std::wstring monacoPrevLogPath = L"logs\\FileExplorer_localLow\\MonacoPrevHandler\\monaco-prev-handler-log.txt";
inline const static std::string pdfPrevLoggerName = "PdfPrevHandler";
inline const static std::wstring pdfPrevLogPath = L"logs\\FileExplorer_localLow\\PdfPrevHandler\\pdf-prev-handler-log.txt";
inline const static std::string pdfThumbLoggerName = "PdfThumbnailProvider";
inline const static std::wstring pdfThumbLogPath = L"logs\\FileExplorer_localLow\\PdfThumbnailProvider\\pdf-thumbnail-provider-log.txt";
inline const static std::string stlThumbLoggerName = "StlThumbnailProvider";
inline const static std::wstring stlThumbLogPath = L"logs\\FileExplorer_localLow\\StlThumbnailProvider\\stl-thumbnail-provider-log.txt";
inline const static std::string svgPrevLoggerName = "SvgPrevHandler";
inline const static std::wstring svgPrevLogPath = L"logs\\FileExplorer_localLow\\SvgPrevHandler\\svg-prev-handler-log.txt";
inline const static std::string svgThumbLoggerName = "SvgThumbnailProvider";
inline const static std::wstring svgThumbLogPath = L"logs\\FileExplorer_localLow\\SvgThumbnailProvider\\svg-thumbnail-provider-log.txt";
inline const static std::string launcherLoggerName = "launcher";
inline const static std::wstring launcherLogPath = L"LogsModuleInterface\\launcher-log.txt";
inline const static std::wstring awakeLogPath = L"Logs\\awake-log.txt";

View File

@ -28,13 +28,12 @@ inline registry::ChangeSet getSvgPreviewHandlerChangeSet(const std::wstring inst
using namespace registry::shellex;
return generatePreviewHandler(PreviewHandlerType::preview,
perUser,
L"{ddee2b8a-6807-48a6-bb20-2338174ff779}",
L"{FCDD4EED-41AA-492F-8A84-31A1546226E0}",
get_std_product_version(),
(fs::path{ installationDir } /
LR"d(modules\FileExplorerPreview\PowerToys.SvgPreviewHandler.comhost.dll)d")
LR"d(modules\FileExplorerPreview\PowerToys.SvgPreviewHandlerCpp.dll)d")
.wstring(),
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.PreviewHandler.Svg.SvgPreviewHandler",
L"SvgPreviewHandler",
L"Svg Preview Handler",
NonLocalizable::ExtSVG);
}
@ -44,11 +43,10 @@ inline registry::ChangeSet getMdPreviewHandlerChangeSet(const std::wstring insta
using namespace registry::shellex;
return generatePreviewHandler(PreviewHandlerType::preview,
perUser,
L"{45769bcc-e8fd-42d0-947e-02beef77a1f5}",
L"{60789D87-9C3C-44AF-B18C-3DE2C2820ED3}",
get_std_product_version(),
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.MarkdownPreviewHandler.comhost.dll)d").wstring(),
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.PreviewHandler.Markdown.MarkdownPreviewHandler",
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.MarkdownPreviewHandlerCpp.dll)d").wstring(),
L"MarkdownPreviewHandler",
L"Markdown Preview Handler",
NonLocalizable::ExtMarkdown);
}
@ -107,11 +105,10 @@ inline registry::ChangeSet getMonacoPreviewHandlerChangeSet(const std::wstring i
return generatePreviewHandler(PreviewHandlerType::preview,
perUser,
L"{afbd5a44-2520-4ae0-9224-6cfce8fe4400}",
L"{D8034CFA-F34B-41FE-AD45-62FCBB52A6DA}",
get_std_product_version(),
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.MonacoPreviewHandler.comhost.dll)d").wstring(),
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.PreviewHandler.Monaco.MonacoPreviewHandler",
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.MonacoPreviewHandlerCpp.dll)d").wstring(),
L"MonacoPreviewHandler",
L"Monaco Preview Handler",
extensions);
}
@ -121,11 +118,10 @@ inline registry::ChangeSet getPdfPreviewHandlerChangeSet(const std::wstring inst
using namespace registry::shellex;
return generatePreviewHandler(PreviewHandlerType::preview,
perUser,
L"{07665729-6243-4746-95b7-79579308d1b2}",
L"{A5A41CC7-02CB-41D4-8C9B-9087040D6098}",
get_std_product_version(),
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.PdfPreviewHandler.comhost.dll)d").wstring(),
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.PreviewHandler.Pdf.PdfPreviewHandler",
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.PdfPreviewHandlerCpp.dll)d").wstring(),
L"PdfPreviewHandler",
L"Pdf Preview Handler",
NonLocalizable::ExtPDF);
}
@ -135,11 +131,10 @@ inline registry::ChangeSet getGcodePreviewHandlerChangeSet(const std::wstring in
using namespace registry::shellex;
return generatePreviewHandler(PreviewHandlerType::preview,
perUser,
L"{ec52dea8-7c9f-4130-a77b-1737d0418507}",
L"{A0257634-8812-4CE8-AF11-FA69ACAEAFAE}",
get_std_product_version(),
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.GcodePreviewHandler.comhost.dll)d").wstring(),
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.PreviewHandler.Gcode.GcodePreviewHandler",
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.GcodePreviewHandlerCpp.dll)d").wstring(),
L"GcodePreviewHandler",
L"G-code Preview Handler",
NonLocalizable::ExtGCode);
}
@ -149,11 +144,10 @@ inline registry::ChangeSet getSvgThumbnailHandlerChangeSet(const std::wstring in
using namespace registry::shellex;
return generatePreviewHandler(PreviewHandlerType::thumbnail,
perUser,
L"{36B27788-A8BB-4698-A756-DF9F11F64F84}",
L"{10144713-1526-46C9-88DA-1FB52807A9FF}",
get_std_product_version(),
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.SvgThumbnailProvider.comhost.dll)d").wstring(),
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.ThumbnailHandler.Svg.SvgThumbnailProvider",
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.SvgThumbnailProviderCpp.dll)d").wstring(),
L"SvgThumbnailProvider",
L"Svg Thumbnail Provider",
NonLocalizable::ExtSVG,
L"Picture");
@ -164,11 +158,10 @@ inline registry::ChangeSet getPdfThumbnailHandlerChangeSet(const std::wstring in
using namespace registry::shellex;
return generatePreviewHandler(PreviewHandlerType::thumbnail,
perUser,
L"{BCC13D15-9720-4CC4-8371-EA74A274741E}",
L"{D8BB9942-93BD-412D-87E4-33FAB214DC1A}",
get_std_product_version(),
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.PdfThumbnailProvider.comhost.dll)d").wstring(),
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.ThumbnailHandler.Pdf.PdfThumbnailProvider",
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.PdfThumbnailProviderCpp.dll)d").wstring(),
L"PdfThumbnailProvider",
L"Pdf Thumbnail Provider",
NonLocalizable::ExtPDF);
}
@ -178,11 +171,10 @@ inline registry::ChangeSet getGcodeThumbnailHandlerChangeSet(const std::wstring
using namespace registry::shellex;
return generatePreviewHandler(PreviewHandlerType::thumbnail,
perUser,
L"{BFEE99B4-B74D-4348-BCA5-E757029647FF}",
L"{F2847CBE-CD03-4C83-A359-1A8052C1B9D5}",
get_std_product_version(),
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.GcodeThumbnailProvider.comhost.dll)d").wstring(),
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.ThumbnailHandler.Gcode.GcodeThumbnailProvider",
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.GcodeThumbnailProviderCpp.dll)d").wstring(),
L"GcodeThumbnailProvider",
L"G-code Thumbnail Provider",
NonLocalizable::ExtGCode);
}
@ -192,11 +184,10 @@ inline registry::ChangeSet getStlThumbnailHandlerChangeSet(const std::wstring in
using namespace registry::shellex;
return generatePreviewHandler(PreviewHandlerType::thumbnail,
perUser,
L"{8BC8AFC2-4E7C-4695-818E-8C1FFDCEA2AF}",
L"{77257004-6F25-4521-B602-50ECC6EC62A6}",
get_std_product_version(),
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.StlThumbnailProvider.comhost.dll)d").wstring(),
registry::DOTNET_COMPONENT_CATEGORY_CLSID,
L"Microsoft.PowerToys.ThumbnailHandler.Stl.StlThumbnailProvider",
(fs::path{ installationDir } / LR"d(modules\FileExplorerPreview\PowerToys.StlThumbnailProviderCpp.dll)d").wstring(),
L"StlThumbnailProvider",
L"Stl Thumbnail Provider",
NonLocalizable::ExtSTL);
}

View File

@ -315,11 +315,10 @@ namespace registry
std::wstring handlerClsid,
std::wstring powertoysVersion,
std::wstring fullPathToHandler,
std::wstring handlerCategory,
std::wstring className,
std::wstring displayName,
std::vector<std::wstring> fileTypes,
std::wstring fileKindType = L"" )
std::wstring fileKindType = L"")
{
const HKEY scope = perUser ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
@ -331,9 +330,6 @@ namespace registry
inprocServerPath += L'\\';
inprocServerPath += L"InprocServer32";
std::wstring implementedCategoriesPath = clsidPath + LR"d(\Implemented Categories\)d";
implementedCategoriesPath += handlerCategory;
std::wstring assemblyKeyValue;
if (const auto lastDotPos = className.rfind(L'.'); lastDotPos != std::wstring::npos)
{
@ -356,13 +352,10 @@ namespace registry
// TODO: verify that we actually need all of those
vec_t changes = { { scope, clsidPath, L"DisplayName", displayName },
{ scope, clsidPath, std::nullopt, className },
{ scope, implementedCategoriesPath, std::nullopt, L"" },
{ scope, inprocServerPath, std::nullopt, fullPathToHandler },
{ scope, inprocServerPath, L"Assembly", assemblyKeyValue },
{ scope, inprocServerPath, L"Class", className },
{ scope, inprocServerPath, L"ThreadingModel", L"Both" },
{ scope, versionPath, L"Assembly", assemblyKeyValue },
{ scope, versionPath, L"Class", className } };
{ scope, inprocServerPath, L"ThreadingModel", L"Apartment" } };
for (const auto& fileType : fileTypes)
{

View File

@ -21,6 +21,15 @@
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
<ApplicationIcon>Assets/Icon.ico</ApplicationIcon>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup>

View File

@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<PublishDir>$(PowerToysRoot)\$(Platform)\$(Configuration)\modules\FileLocksmith</PublishDir>
<RuntimeIdentifier>win10-$(Platform)</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun>False</PublishReadyToRun>
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>

View File

@ -20,6 +20,15 @@
<AssemblyName>PowerToys.Hosts</AssemblyName>
<DefineConstants>DISABLE_XAML_GENERATED_MAIN,TRACE</DefineConstants>
<ApplicationIcon>Assets/Hosts.ico</ApplicationIcon>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->

View File

@ -13,7 +13,6 @@
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x86;x64;arm64</Platforms>
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
<PublishProfile>win10-$(Platform).pubxml</PublishProfile>
<UseWinUI>true</UseWinUI>
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
@ -22,6 +21,14 @@
<WindowsPackageType>None</WindowsPackageType>
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->

View File

@ -10,6 +10,15 @@
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup>

View File

@ -17,6 +17,15 @@
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
<PackageProjectUrl>https://awake.den.dev</PackageProjectUrl>
<RepositoryUrl>https://github.com/microsoft/powertoys</RepositoryUrl>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->

View File

@ -9,7 +9,17 @@
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<UseWPF>true</UseWPF>
<StartupObject>ColorPicker.Program</StartupObject>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup>
<ProjectGuid>{BA58206B-1493-4C75-BFEA-A85768A1E156}</ProjectGuid>
<OutputType>WinExe</OutputType>

View File

@ -11,9 +11,18 @@
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones</OutputPath>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones</OutputPath>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup>
<ProjectGuid>{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}</ProjectGuid>
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>

View File

@ -8,8 +8,17 @@
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<UseWPF>true</UseWPF>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup>
<ProjectGuid>{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}</ProjectGuid>
<OutputType>WinExe</OutputType>

View File

@ -19,8 +19,16 @@
<AssemblyName>PowerToys.PowerLauncher</AssemblyName>
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\modules\launcher\</OutputPath>
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<DefineConstants>DEBUG;TRACE</DefineConstants>

View File

@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<PublishDir>$(PowerToysRoot)\$(Platform)\$(Configuration)\modules\launcher</PublishDir>
<RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun>False</PublishReadyToRun>
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>

View File

@ -7,8 +7,18 @@
<Nullable>disable</Nullable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
<UseWindowsForms>true</UseWindowsForms>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup>
<CsWinRTIncludes>PowerToys.GPOWrapper;PowerToys.PowerAccentKeyboardService</CsWinRTIncludes>
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>

View File

@ -10,10 +10,19 @@
<ApplicationIcon>icon.ico</ApplicationIcon>
<AssemblyName>PowerToys.PowerAccent</AssemblyName>
<XamlDebuggingInformation>True</XamlDebuggingInformation>
<StartupObject>PowerAccent.UI.Program</StartupObject>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\PowerAccent</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<StartupObject>PowerAccent.UI.Program</StartupObject>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\PowerAccent</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>

View File

@ -1,71 +0,0 @@
// 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.Gcode
{
/// <summary>
/// Extends <see cref="StreamBasedPreviewHandler"/> for Gcode Preview Handler.
/// </summary>
[Guid("ec52dea8-7c9f-4130-a77b-1737d0418507")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class GcodePreviewHandler : StreamBasedPreviewHandler, IDisposable
{
private GcodePreviewHandlerControl _gcodePreviewControl;
private bool disposedValue;
/// <summary>
/// Initializes a new instance of the <see cref="GcodePreviewHandler"/> class.
/// </summary>
public GcodePreviewHandler()
{
Initialize();
}
/// <inheritdoc/>
public override void DoPreview()
{
_gcodePreviewControl.DoPreview(Stream);
}
/// <inheritdoc/>
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
{
PowerToysTelemetry.Log.WriteEvent(new Telemetry.Events.GcodeFileHandlerLoaded());
_gcodePreviewControl = new GcodePreviewHandlerControl();
return _gcodePreviewControl;
}
/// <summary>
/// Disposes objects
/// </summary>
/// <param name="disposing">Is Disposing</param>
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
_gcodePreviewControl.Dispose();
}
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);
}
}
}

View File

@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<UseWindowsForms>true</UseWindowsForms>
<AssemblyTitle>PowerToys.GcodePreviewHandler</AssemblyTitle>
<AssemblyDescription>PowerToys GcodePreviewHandler</AssemblyDescription>
@ -11,13 +12,21 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<AssemblyName>PowerToys.GcodePreviewHandler</AssemblyName>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup>
<ProjectGuid>{805306FF-A562-4415-8DEF-E493BDC45918}</ProjectGuid>
<RootNamespace>Microsoft.PowerToys.PreviewHandler.Gcode</RootNamespace>
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<EnableComHosting>true</EnableComHosting>
</PropertyGroup>
<Import Project="..\..\..\Version.props" />
@ -40,6 +49,7 @@
<PropertyGroup>
<!-- Disable missing comment warning. WinRT/C++ libraries added won't have comments on their reflections. -->
<NoWarn>$(NoWarn);1591</NoWarn>
<OutputType>WinExe</OutputType>
</PropertyGroup>
<ItemGroup>
@ -48,7 +58,9 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\Common.UI\Common.UI.csproj" />
<ProjectReference Include="..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
<ProjectReference Include="..\..\..\common\interop\PowerToys.Interop.vcxproj" />
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
<ProjectReference Include="..\common\PreviewHandlerCommon.csproj" />
</ItemGroup>

View File

@ -46,52 +46,50 @@ namespace Microsoft.PowerToys.PreviewHandler.Gcode
if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredGcodePreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
{
// GPO is disabling this utility. Show an error message instead.
InvokeOnControlThread(() =>
{
_infoBarAdded = true;
AddTextBoxControl(Properties.Resource.GpoDisabledErrorText);
Resize += FormResized;
base.DoPreview(dataSource);
});
_infoBarAdded = true;
AddTextBoxControl(Properties.Resource.GpoDisabledErrorText);
Resize += FormResized;
base.DoPreview(dataSource);
return;
}
InvokeOnControlThread(() =>
try
{
try
Bitmap thumbnail = null;
if (!(dataSource is string filePath))
{
Bitmap thumbnail = null;
using (var stream = new ReadonlyStream(dataSource as IStream))
{
using (var reader = new StreamReader(stream))
{
thumbnail = GetThumbnail(reader);
}
}
_infoBarAdded = false;
if (thumbnail == null)
{
_infoBarAdded = true;
AddTextBoxControl(Properties.Resource.GcodeWithoutEmbeddedThumbnails);
}
else
{
AddPictureBoxControl(thumbnail);
}
Resize += FormResized;
base.DoPreview(dataSource);
PowerToysTelemetry.Log.WriteEvent(new GcodeFilePreviewed());
throw new ArgumentException($"{nameof(dataSource)} for {nameof(GcodePreviewHandlerControl)} must be a string but was a '{typeof(T)}'");
}
catch (Exception ex)
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
using (var reader = new StreamReader(fs))
{
PreviewError(ex, dataSource);
thumbnail = GetThumbnail(reader);
}
});
_infoBarAdded = false;
if (thumbnail == null)
{
_infoBarAdded = true;
AddTextBoxControl(Properties.Resource.GcodeWithoutEmbeddedThumbnails);
}
else
{
AddPictureBoxControl(thumbnail);
}
Resize += FormResized;
base.DoPreview(fs);
PowerToysTelemetry.Log.WriteEvent(new GcodeFilePreviewed());
}
catch (Exception ex)
{
PreviewError(ex, dataSource);
}
}
/// <summary>

View File

@ -0,0 +1,63 @@
// 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.
namespace Microsoft.PowerToys.PreviewHandler.Gcode
{
using System.Globalization;
using System.Windows.Threading;
using Common.UI;
using interop;
internal static class Program
{
private static CancellationTokenSource _tokenSource = new CancellationTokenSource();
private static GcodePreviewHandlerControl _previewHandlerControl;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Main(string[] args)
{
ApplicationConfiguration.Initialize();
if (args != null)
{
if (args.Length == 6)
{
string filePath = args[0];
int hwnd = Convert.ToInt32(args[1], 16);
Rectangle s = default(Rectangle);
int left = Convert.ToInt32(args[2], 10);
int right = Convert.ToInt32(args[3], 10);
int top = Convert.ToInt32(args[4], 10);
int bottom = Convert.ToInt32(args[5], 10);
_previewHandlerControl = new GcodePreviewHandlerControl();
_previewHandlerControl.SetWindow((IntPtr)hwnd, s);
_previewHandlerControl.DoPreview(filePath);
NativeEventWaiter.WaitForEventLoop(
Constants.GcodePreviewResizeEvent(),
() =>
{
Rectangle s = default(Rectangle);
_previewHandlerControl.SetRect(s);
},
Dispatcher.CurrentDispatcher,
_tokenSource.Token);
}
else
{
MessageBox.Show("Wrong number of args: " + args.Length.ToString(CultureInfo.InvariantCulture));
}
}
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
Application.Run();
}
}
}

View File

@ -0,0 +1,84 @@
#include "pch.h"
#include "ClassFactory.h"
#include "GcodePreviewHandler.h"
#include <new>
#include <Shlwapi.h>
extern long g_cDllRef;
ClassFactory::ClassFactory() :
m_cRef(1)
{
InterlockedIncrement(&g_cDllRef);
}
ClassFactory::~ClassFactory()
{
InterlockedDecrement(&g_cDllRef);
}
//
// IUnknown
//
IFACEMETHODIMP ClassFactory::QueryInterface(REFIID riid, void **ppv)
{
static const QITAB qit[] = {
QITABENT(ClassFactory, IClassFactory),
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG) ClassFactory::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
IFACEMETHODIMP_(ULONG) ClassFactory::Release()
{
ULONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
}
return cRef;
}
//
// IClassFactory
//
IFACEMETHODIMP ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
HRESULT hr = CLASS_E_NOAGGREGATION;
if (pUnkOuter == NULL)
{
hr = E_OUTOFMEMORY;
GcodePreviewHandler* pExt = new (std::nothrow) GcodePreviewHandler();
if (pExt)
{
hr = pExt->QueryInterface(riid, ppv);
pExt->Release();
}
}
return hr;
}
IFACEMETHODIMP ClassFactory::LockServer(BOOL fLock)
{
if (fLock)
{
InterlockedIncrement(&g_cDllRef);
}
else
{
InterlockedDecrement(&g_cDllRef);
}
return S_OK;
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <Unknwn.h>
class ClassFactory : public IClassFactory
{
public:
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv);
IFACEMETHODIMP_(ULONG) AddRef();
IFACEMETHODIMP_(ULONG) Release();
// IClassFactory
IFACEMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppv);
IFACEMETHODIMP LockServer(BOOL fLock);
ClassFactory();
protected:
~ClassFactory();
private:
long m_cRef;
};

View File

@ -0,0 +1,262 @@
#include "pch.h"
#include "GcodePreviewHandler.h"
#include <shellapi.h>
#include <Shlwapi.h>
#include <string>
#include <common/interop/shared_constants.h>
#include <common/logger/logger.h>
#include <common/SettingsAPI/settings_helpers.h>
#include <common/utils/process_path.h>
extern HINSTANCE g_hInst;
extern long g_cDllRef;
GcodePreviewHandler::GcodePreviewHandler() :
m_cRef(1), m_hwndParent(NULL), m_rcParent(), m_punkSite(NULL), m_process(NULL)
{
m_resizeEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::GCODE_PREVIEW_RESIZE_EVENT);
std::filesystem::path logFilePath(PTSettingsHelper::get_local_low_folder_location());
logFilePath.append(LogSettings::gcodePrevLogPath);
Logger::init(LogSettings::gcodePrevLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
InterlockedIncrement(&g_cDllRef);
}
GcodePreviewHandler::~GcodePreviewHandler()
{
InterlockedDecrement(&g_cDllRef);
}
#pragma region IUnknown
IFACEMETHODIMP GcodePreviewHandler::QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] = {
QITABENT(GcodePreviewHandler, IPreviewHandler),
QITABENT(GcodePreviewHandler, IInitializeWithFile),
QITABENT(GcodePreviewHandler, IPreviewHandlerVisuals),
QITABENT(GcodePreviewHandler, IOleWindow),
QITABENT(GcodePreviewHandler, IObjectWithSite),
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG)
GcodePreviewHandler::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
IFACEMETHODIMP_(ULONG)
GcodePreviewHandler::Release()
{
ULONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
}
return cRef;
}
#pragma endregion
#pragma region IInitializationWithFile
IFACEMETHODIMP GcodePreviewHandler::Initialize(LPCWSTR pszFilePath, DWORD grfMode)
{
m_filePath = pszFilePath;
return S_OK;
}
#pragma endregion
#pragma region IPreviewHandler
IFACEMETHODIMP GcodePreviewHandler::SetWindow(HWND hwnd, const RECT* prc)
{
if (hwnd && prc)
{
m_hwndParent = hwnd;
m_rcParent = *prc;
}
return S_OK;
}
IFACEMETHODIMP GcodePreviewHandler::SetFocus()
{
return S_OK;
}
IFACEMETHODIMP GcodePreviewHandler::QueryFocus(HWND* phwnd)
{
HRESULT hr = E_INVALIDARG;
if (phwnd)
{
*phwnd = ::GetFocus();
if (*phwnd)
{
hr = S_OK;
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
return hr;
}
IFACEMETHODIMP GcodePreviewHandler::TranslateAccelerator(MSG* pmsg)
{
HRESULT hr = S_FALSE;
IPreviewHandlerFrame* pFrame = NULL;
if (m_punkSite && SUCCEEDED(m_punkSite->QueryInterface(&pFrame)))
{
hr = pFrame->TranslateAccelerator(pmsg);
pFrame->Release();
}
return hr;
}
IFACEMETHODIMP GcodePreviewHandler::SetRect(const RECT* prc)
{
HRESULT hr = E_INVALIDARG;
if (prc != NULL)
{
if (!m_resizeEvent)
{
Logger::error(L"Failed to create resize event for GcodePreviewHandler");
}
else
{
if (m_rcParent.right != prc->right || m_rcParent.left != prc->left || m_rcParent.top != prc->top || m_rcParent.bottom != prc->bottom)
{
if (!SetEvent(m_resizeEvent))
{
Logger::error(L"Failed to signal resize event for GcodePreviewHandler");
}
}
}
m_rcParent = *prc;
hr = S_OK;
}
return hr;
}
IFACEMETHODIMP GcodePreviewHandler::DoPreview()
{
try
{
Logger::info(L"Starting GcodePreviewHandler.exe");
STARTUPINFO info = { sizeof(info) };
std::wstring cmdLine{ L"\"" + m_filePath + L"\"" };
cmdLine += L" ";
std::wostringstream ss;
ss << std::hex << m_hwndParent;
cmdLine += ss.str();
cmdLine += L" ";
cmdLine += std::to_wstring(m_rcParent.left);
cmdLine += L" ";
cmdLine += std::to_wstring(m_rcParent.right);
cmdLine += L" ";
cmdLine += std::to_wstring(m_rcParent.top);
cmdLine += L" ";
cmdLine += std::to_wstring(m_rcParent.bottom);
std::wstring appPath = get_module_folderpath(g_hInst) + L"\\PowerToys.GcodePreviewHandler.exe";
SHELLEXECUTEINFO sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = appPath.c_str();
sei.lpParameters = cmdLine.c_str();
sei.nShow = SW_SHOWDEFAULT;
ShellExecuteEx(&sei);
m_process = sei.hProcess;
}
catch (std::exception& e)
{
std::wstring errorMessage = std::wstring{ winrt::to_hstring(e.what()) };
Logger::error(L"Failed to start GcodePreviewHandler.exe. Error: {}", errorMessage);
}
return S_OK;
}
IFACEMETHODIMP GcodePreviewHandler::Unload()
{
Logger::info(L"Unload and terminate .exe");
m_hwndParent = NULL;
TerminateProcess(m_process, 0);
return S_OK;
}
#pragma endregion
#pragma region IPreviewHandlerVisuals
IFACEMETHODIMP GcodePreviewHandler::SetBackgroundColor(COLORREF color)
{
return S_OK;
}
IFACEMETHODIMP GcodePreviewHandler::SetFont(const LOGFONTW* plf)
{
return S_OK;
}
IFACEMETHODIMP GcodePreviewHandler::SetTextColor(COLORREF color)
{
return S_OK;
}
#pragma endregion
#pragma region IOleWindow
IFACEMETHODIMP GcodePreviewHandler::GetWindow(HWND* phwnd)
{
HRESULT hr = E_INVALIDARG;
if (phwnd)
{
*phwnd = m_hwndParent;
hr = S_OK;
}
return hr;
}
IFACEMETHODIMP GcodePreviewHandler::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
}
#pragma endregion
#pragma region IObjectWithSite
IFACEMETHODIMP GcodePreviewHandler::SetSite(IUnknown* punkSite)
{
if (m_punkSite)
{
m_punkSite->Release();
m_punkSite = NULL;
}
return punkSite ? punkSite->QueryInterface(&m_punkSite) : S_OK;
}
IFACEMETHODIMP GcodePreviewHandler::GetSite(REFIID riid, void** ppv)
{
*ppv = NULL;
return m_punkSite ? m_punkSite->QueryInterface(riid, ppv) : E_FAIL;
}
#pragma endregion
#pragma region Helper Functions
#pragma endregion

View File

@ -0,0 +1,69 @@
#pragma once
#include "pch.h"
#include <filesystem>
#include <ShlObj.h>
#include <string>
class GcodePreviewHandler :
public IInitializeWithFile,
public IPreviewHandler,
public IPreviewHandlerVisuals,
public IOleWindow,
public IObjectWithSite
{
public:
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv);
IFACEMETHODIMP_(ULONG) AddRef();
IFACEMETHODIMP_(ULONG) Release();
// IInitializeWithFile
IFACEMETHODIMP Initialize(LPCWSTR pszFilePath, DWORD grfMode);
// IPreviewHandler
IFACEMETHODIMP SetWindow(HWND hwnd, const RECT* prc);
IFACEMETHODIMP SetFocus();
IFACEMETHODIMP QueryFocus(HWND* phwnd);
IFACEMETHODIMP TranslateAccelerator(MSG* pmsg);
IFACEMETHODIMP SetRect(const RECT* prc);
IFACEMETHODIMP DoPreview();
IFACEMETHODIMP Unload();
// IPreviewHandlerVisuals
IFACEMETHODIMP SetBackgroundColor(COLORREF color);
IFACEMETHODIMP SetFont(const LOGFONTW* plf);
IFACEMETHODIMP SetTextColor(COLORREF color);
// IOleWindow
IFACEMETHODIMP GetWindow(HWND* phwnd);
IFACEMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
// IObjectWithSite
IFACEMETHODIMP SetSite(IUnknown* punkSite);
IFACEMETHODIMP GetSite(REFIID riid, void** ppv);
GcodePreviewHandler();
protected:
~GcodePreviewHandler();
private:
// Reference count of component.
long m_cRef;
// Provided during initialization.
std::wstring m_filePath;
// Parent window that hosts the previewer window.
// Note: do NOT DestroyWindow this.
HWND m_hwndParent;
// Bounding rect of the parent window.
RECT m_rcParent;
// Site pointer from host, used to get IPreviewHandlerFrame.
IUnknown* m_punkSite;
HANDLE m_process;
HANDLE m_resizeEvent;
};

View File

@ -0,0 +1,40 @@
#include <windows.h>
#include "resource.h"
#include "../../../common/version/version.h"
#define APSTUDIO_READONLY_SYMBOLS
#include "winres.h"
#undef APSTUDIO_READONLY_SYMBOLS
1 VERSIONINFO
FILEVERSION FILE_VERSION
PRODUCTVERSION PRODUCT_VERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
BEGIN
VALUE "CompanyName", COMPANY_NAME
VALUE "FileDescription", FILE_DESCRIPTION
VALUE "FileVersion", FILE_VERSION_STRING
VALUE "InternalName", INTERNAL_NAME
VALUE "LegalCopyright", COPYRIGHT_NOTE
VALUE "OriginalFilename", ORIGINAL_FILENAME
VALUE "ProductName", PRODUCT_NAME
VALUE "ProductVersion", PRODUCT_VERSION_STRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
END
END

View File

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{5a5dd09d-723a-44d3-8f2b-293584c3d731}</ProjectGuid>
<RootNamespace>GcodePreviewHandlerCpp</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</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">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\</OutDir>
</PropertyGroup>
<PropertyGroup>
<TargetName>PowerToys.$(ProjectName)</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;MARKDOWNPREVIEWHANDLERCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>../../..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>GlobalExportFunctions.def</ModuleDefinitionFile>
<AdditionalDependencies>Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;MARKDOWNPREVIEWHANDLERCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>../../..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>GlobalExportFunctions.def</ModuleDefinitionFile>
<AdditionalDependencies>Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="ClassFactory.h" />
<ClInclude Include="GcodePreviewHandler.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ClassFactory.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="GcodePreviewHandler.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="GlobalExportFunctions.def" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="GcodePreviewHandlerCpp.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\common\SettingsAPI\SettingsAPI.vcxproj">
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="..\..\..\..\deps\spdlog.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ClassFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GcodePreviewHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Resource Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ClassFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GcodePreviewHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="GlobalExportFunctions.def">
<Filter>Source Files</Filter>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="GcodePreviewHandlerCpp.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,3 @@
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE

View File

@ -0,0 +1,73 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include "ClassFactory.h"
HINSTANCE g_hInst = NULL;
long g_cDllRef = 0;
// {A0257634-8812-4CE8-AF11-FA69ACAEAFAE}
static const GUID CLSID_GcodePreviewHandler = { 0xa0257634, 0x8812, 0x4ce8, { 0xaf, 0x11, 0xfa, 0x69, 0xac, 0xae, 0xaf, 0xae } };
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hInst = hModule;
DisableThreadLibraryCalls(hModule);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//
// FUNCTION: DllGetClassObject
//
// PURPOSE: Create the class factory and query to the specific interface.
//
// PARAMETERS:
// * rclsid - The CLSID that will associate the correct data and code.
// * riid - A reference to the identifier of the interface that the caller
// is to use to communicate with the class object.
// * ppv - The address of a pointer variable that receives the interface
// pointer requested in riid. Upon successful return, *ppv contains the
// requested interface pointer. If an error occurs, the interface pointer
// is NULL.
//
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
{
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
if (IsEqualCLSID(CLSID_GcodePreviewHandler, rclsid))
{
hr = E_OUTOFMEMORY;
ClassFactory* pClassFactory = new ClassFactory();
if (pClassFactory)
{
hr = pClassFactory->QueryInterface(riid, ppv);
pClassFactory->Release();
}
}
return hr;
}
//
// FUNCTION: DllCanUnloadNow
//
// PURPOSE: Check if we can unload the component from the memory.
//
// NOTE: The component can be unloaded from the memory when its reference
// count is zero (i.e. nobody is still using the component).
//
STDAPI DllCanUnloadNow(void)
{
return g_cDllRef > 0 ? S_FALSE : S_OK;
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.220929.3" targetFramework="native" />
</packages>

View File

@ -0,0 +1,5 @@
// pch.cpp: source file corresponding to the pre-compiled header
#include "pch.h"
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.

View File

@ -0,0 +1,14 @@
// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.
#ifndef PCH_H
#define PCH_H
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
#endif //PCH_H

View File

@ -0,0 +1,13 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by AlwaysOnTopModuleInterface.rc
//////////////////////////////
// Non-localizable
#define FILE_DESCRIPTION "PowerToys Gcode Preview Handler Module"
#define INTERNAL_NAME "PowerToys.GcodePreviewHandlerCpp"
#define ORIGINAL_FILENAME "PowerToys.GcodePreviewHandlerCpp.dll"
// Non-localizable
//////////////////////////////

View File

@ -1,32 +1,31 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using Common.ComInterlop;
using Common.Utilities;
namespace Microsoft.PowerToys.ThumbnailHandler.Gcode
{
/// <summary>
/// G-code Thumbnail Provider.
/// </summary>
[Guid("BFEE99B4-B74D-4348-BCA5-E757029647FF")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class GcodeThumbnailProvider : IInitializeWithStream, IThumbnailProvider
public class GcodeThumbnailProvider
{
public GcodeThumbnailProvider(string filePath)
{
FilePath = filePath;
Stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
}
/// <summary>
/// Gets the file path to the file creating thumbnail for.
/// </summary>
public string FilePath { get; private set; }
/// <summary>
/// Gets the stream object to access file.
/// </summary>
public IStream Stream { get; private set; }
public Stream Stream { get; private set; }
/// <summary>
/// The maximum dimension (width or height) thumbnail we will generate.
@ -140,44 +139,36 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Gcode
return destImage;
}
/// <inheritdoc/>
public void Initialize(IStream pstream, uint grfMode)
/// <summary>
/// Generate thumbnail bitmap for provided Gcode file/stream.
/// </summary>
/// <param name="cx">Maximum thumbnail size, in pixels.</param>
/// <returns>Generated bitmap</returns>
public Bitmap GetThumbnail(uint cx)
{
// Ignore the grfMode always use read mode to access the file.
this.Stream = pstream;
}
/// <inheritdoc/>
public void GetThumbnail(uint cx, out IntPtr phbmp, out WTS_ALPHATYPE pdwAlpha)
{
phbmp = IntPtr.Zero;
pdwAlpha = WTS_ALPHATYPE.WTSAT_UNKNOWN;
if (cx == 0 || cx > MaxThumbnailSize)
{
return;
return null;
}
if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredGcodeThumbnailsEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
{
// GPO is disabling this utility.
return;
return null;
}
using (var stream = new ReadonlyStream(this.Stream as IStream))
using (var reader = new StreamReader(this.Stream))
{
using (var reader = new StreamReader(stream))
using (Bitmap thumbnail = GetThumbnail(reader, cx))
{
using (Bitmap thumbnail = GetThumbnail(reader, cx))
if (thumbnail != null && thumbnail.Size.Width > 0 && thumbnail.Size.Height > 0)
{
if (thumbnail != null && thumbnail.Size.Width > 0 && thumbnail.Size.Height > 0)
{
phbmp = thumbnail.GetHbitmap(Color.Transparent);
pdwAlpha = WTS_ALPHATYPE.WTSAT_ARGB;
}
return (Bitmap)thumbnail.Clone();
}
}
}
return null;
}
}
}

View File

@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<UseWindowsForms>true</UseWindowsForms>
<ProjectGuid>{809AA252-E17A-4FA2-B0A1-0450976B763F}</ProjectGuid>
<RootNamespace>Microsoft.PowerToys.ThumbnailHandler.Gcode</RootNamespace>
@ -7,13 +8,21 @@
<AssemblyTitle>PowerToys.GcodeThumbnailProvider</AssemblyTitle>
<AssemblyDescription>PowerToys GcodePreviewHandler</AssemblyDescription>
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<EnableComHosting>true</EnableComHosting>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Description>PowerToys GcodePreviewHandler</Description>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<Import Project="..\..\..\Version.props" />
@ -27,6 +36,7 @@
<PropertyGroup>
<!-- Disable missing comment warning. WinRT/C++ libraries added won't have comments on their reflections. -->
<NoWarn>$(NoWarn);1591</NoWarn>
<OutputType>WinExe</OutputType>
</PropertyGroup>
<ItemGroup>

View File

@ -0,0 +1,39 @@
// 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.
namespace Microsoft.PowerToys.ThumbnailHandler.Gcode
{
using System.Globalization;
internal static class Program
{
private static GcodeThumbnailProvider _thumbnailProvider;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Main(string[] args)
{
ApplicationConfiguration.Initialize();
if (args != null)
{
if (args.Length == 2)
{
string filePath = args[0];
uint cx = Convert.ToUInt32(args[1], 10);
_thumbnailProvider = new GcodeThumbnailProvider(filePath);
Bitmap thumbnail = _thumbnailProvider.GetThumbnail(cx);
filePath = filePath.Replace(".gcode", ".bmp");
thumbnail.Save(filePath, System.Drawing.Imaging.ImageFormat.Bmp);
}
else
{
MessageBox.Show("Gcode thumbnail - wrong number of args: " + args.Length.ToString(CultureInfo.InvariantCulture));
}
}
}
}
}

View File

@ -0,0 +1,84 @@
#include "pch.h"
#include "ClassFactory.h"
#include "GcodeThumbnailProvider.h"
#include <new>
#include <Shlwapi.h>
extern long g_cDllRef;
ClassFactory::ClassFactory() :
m_cRef(1)
{
InterlockedIncrement(&g_cDllRef);
}
ClassFactory::~ClassFactory()
{
InterlockedDecrement(&g_cDllRef);
}
//
// IUnknown
//
IFACEMETHODIMP ClassFactory::QueryInterface(REFIID riid, void **ppv)
{
static const QITAB qit[] = {
QITABENT(ClassFactory, IClassFactory),
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG) ClassFactory::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
IFACEMETHODIMP_(ULONG) ClassFactory::Release()
{
ULONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
}
return cRef;
}
//
// IClassFactory
//
IFACEMETHODIMP ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
HRESULT hr = CLASS_E_NOAGGREGATION;
if (pUnkOuter == NULL)
{
hr = E_OUTOFMEMORY;
GcodeThumbnailProvider* pExt = new (std::nothrow) GcodeThumbnailProvider();
if (pExt)
{
hr = pExt->QueryInterface(riid, ppv);
pExt->Release();
}
}
return hr;
}
IFACEMETHODIMP ClassFactory::LockServer(BOOL fLock)
{
if (fLock)
{
InterlockedIncrement(&g_cDllRef);
}
else
{
InterlockedDecrement(&g_cDllRef);
}
return S_OK;
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <Unknwn.h>
class ClassFactory : public IClassFactory
{
public:
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv);
IFACEMETHODIMP_(ULONG) AddRef();
IFACEMETHODIMP_(ULONG) Release();
// IClassFactory
IFACEMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppv);
IFACEMETHODIMP LockServer(BOOL fLock);
ClassFactory();
protected:
~ClassFactory();
private:
long m_cRef;
};

View File

@ -0,0 +1,185 @@
#include "pch.h"
#include "GcodeThumbnailProvider.h"
#include <filesystem>
#include <fstream>
#include <shellapi.h>
#include <Shlwapi.h>
#include <string>
#include <wil/com.h>
#include <common/utils/process_path.h>
#include <common/interop/shared_constants.h>
#include <common/logger/logger.h>
#include <common/SettingsAPI/settings_helpers.h>
#include <common/utils/process_path.h>
extern HINSTANCE g_hInst;
extern long g_cDllRef;
GcodeThumbnailProvider::GcodeThumbnailProvider() :
m_cRef(1), m_pStream(NULL), m_process(NULL)
{
std::filesystem::path logFilePath(PTSettingsHelper::get_local_low_folder_location());
logFilePath.append(LogSettings::gcodeThumbLogPath);
Logger::init(LogSettings::gcodeThumbLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
InterlockedIncrement(&g_cDllRef);
}
GcodeThumbnailProvider::~GcodeThumbnailProvider()
{
InterlockedDecrement(&g_cDllRef);
}
#pragma region IUnknown
IFACEMETHODIMP GcodeThumbnailProvider::QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] = {
QITABENT(GcodeThumbnailProvider, IThumbnailProvider),
QITABENT(GcodeThumbnailProvider, IInitializeWithStream),
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG)
GcodeThumbnailProvider::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
IFACEMETHODIMP_(ULONG)
GcodeThumbnailProvider::Release()
{
ULONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
}
return cRef;
}
#pragma endregion
#pragma region IInitializationWithStream
IFACEMETHODIMP GcodeThumbnailProvider::Initialize(IStream* pStream, DWORD grfMode)
{
HRESULT hr = E_INVALIDARG;
if (pStream)
{
// Initialize can be called more than once, so release existing valid
// m_pStream.
if (m_pStream)
{
m_pStream->Release();
m_pStream = NULL;
}
m_pStream = pStream;
m_pStream->AddRef();
hr = S_OK;
}
return hr;
}
#pragma endregion
#pragma region IThumbnailProvider
IFACEMETHODIMP GcodeThumbnailProvider::GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha)
{
// Read stream into the buffer
char buffer[4096];
ULONG cbRead;
Logger::trace(L"Begin");
GUID guid;
if (CoCreateGuid(&guid) == S_OK)
{
wil::unique_cotaskmem_string guidString;
if (SUCCEEDED(StringFromCLSID(guid, &guidString)))
{
Logger::info(L"Read stream and save to tmp file.");
// {CLSID} -> CLSID
std::wstring guid = std::wstring(guidString.get()).substr(1, std::wstring(guidString.get()).size() - 2);
std::wstring filePath = PTSettingsHelper::get_local_low_folder_location() + L"\\GCodeThumbnail-Temp\\";
if (!std::filesystem::exists(filePath))
{
std::filesystem::create_directories(filePath);
}
std::wstring fileName = filePath + guid + L".gcode";
// Write data to tmp file
std::fstream file;
file.open(fileName, std::ios_base::out | std::ios_base::binary);
if (!file.is_open())
{
return 0;
}
while (true)
{
auto result = m_pStream->Read(buffer, 4096, &cbRead);
file.write(buffer, cbRead);
if (result == S_FALSE)
{
break;
}
}
file.close();
try
{
Logger::info(L"Start GcodeThumbnailProvider.exe");
STARTUPINFO info = { sizeof(info) };
std::wstring cmdLine{ L"\"" + fileName + L"\"" };
cmdLine += L" ";
cmdLine += std::to_wstring(cx);
std::wstring appPath = get_module_folderpath(g_hInst) + L"\\PowerToys.GcodeThumbnailProvider.exe";
SHELLEXECUTEINFO sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = appPath.c_str();
sei.lpParameters = cmdLine.c_str();
sei.nShow = SW_SHOWDEFAULT;
ShellExecuteEx(&sei);
m_process = sei.hProcess;
WaitForSingleObject(m_process, INFINITE);
std::filesystem::remove(fileName);
std::wstring fileNameBmp = filePath + guid + L".bmp";
*phbmp = (HBITMAP)LoadImage(NULL, fileNameBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
*pdwAlpha = WTS_ALPHATYPE::WTSAT_ARGB;
std::filesystem::remove(fileNameBmp);
}
catch (std::exception& e)
{
std::wstring errorMessage = std::wstring{ winrt::to_hstring(e.what()) };
Logger::error(L"Failed to start GcodeThumbnailProvider.exe. Error: {}", errorMessage);
}
}
}
return S_OK;
}
#pragma endregion
#pragma region Helper Functions
#pragma endregion

View File

@ -0,0 +1,37 @@
#pragma once
#include "pch.h"
#include <ShlObj.h>
#include <string>
#include <thumbcache.h>
class GcodeThumbnailProvider :
public IInitializeWithStream,
public IThumbnailProvider
{
public:
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv);
IFACEMETHODIMP_(ULONG) AddRef();
IFACEMETHODIMP_(ULONG) Release();
// IInitializeWithStream
IFACEMETHODIMP Initialize(IStream* pstream, DWORD grfMode);
// IPreviewHandler
IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha);
GcodeThumbnailProvider();
protected:
~GcodeThumbnailProvider();
private:
// Reference count of component.
long m_cRef;
// Provided during initialization.
IStream* m_pStream;
HANDLE m_process;
};

View File

@ -0,0 +1,40 @@
#include <windows.h>
#include "resource.h"
#include "../../../common/version/version.h"
#define APSTUDIO_READONLY_SYMBOLS
#include "winres.h"
#undef APSTUDIO_READONLY_SYMBOLS
1 VERSIONINFO
FILEVERSION FILE_VERSION
PRODUCTVERSION PRODUCT_VERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
BEGIN
VALUE "CompanyName", COMPANY_NAME
VALUE "FileDescription", FILE_DESCRIPTION
VALUE "FileVersion", FILE_VERSION_STRING
VALUE "InternalName", INTERNAL_NAME
VALUE "LegalCopyright", COPYRIGHT_NOTE
VALUE "OriginalFilename", ORIGINAL_FILENAME
VALUE "ProductName", PRODUCT_NAME
VALUE "ProductVersion", PRODUCT_VERSION_STRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
END
END

View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{56cc2f10-6e41-453d-be16-c593a5e58482}</ProjectGuid>
<RootNamespace>GcodeThumbnailProviderCpp</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</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">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\</OutDir>
</PropertyGroup>
<PropertyGroup>
<TargetName>PowerToys.$(ProjectName)</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;MARKDOWNPREVIEWHANDLERCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>../../..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>GlobalExportFunctions.def</ModuleDefinitionFile>
<AdditionalDependencies>Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;MARKDOWNPREVIEWHANDLERCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>../../..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>GlobalExportFunctions.def</ModuleDefinitionFile>
<AdditionalDependencies>Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="ClassFactory.h" />
<ClInclude Include="GcodeThumbnailProvider.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ClassFactory.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="GcodeThumbnailProvider.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="GlobalExportFunctions.def" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\common\SettingsAPI\SettingsAPI.vcxproj">
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="GcodeThumbnailProviderCpp.rc" />
</ItemGroup>
<Import Project="..\..\..\..\deps\spdlog.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
</Target>
</Project>

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ClassFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GcodeThumbnailProvider.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Resource Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ClassFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GcodeThumbnailProvider.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="GlobalExportFunctions.def">
<Filter>Source Files</Filter>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="GcodeThumbnailProviderCpp.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,3 @@
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE

View File

@ -0,0 +1,73 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include "ClassFactory.h"
HINSTANCE g_hInst = NULL;
long g_cDllRef = 0;
// {F2847CBE-CD03-4C83-A359-1A8052C1B9D5}
static const GUID CLSID_GcodeThumbnailProvider = { 0xf2847cbe, 0xcd03, 0x4c83, { 0xa3, 0x59, 0x1a, 0x80, 0x52, 0xc1, 0xb9, 0xd5 } };
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hInst = hModule;
DisableThreadLibraryCalls(hModule);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//
// FUNCTION: DllGetClassObject
//
// PURPOSE: Create the class factory and query to the specific interface.
//
// PARAMETERS:
// * rclsid - The CLSID that will associate the correct data and code.
// * riid - A reference to the identifier of the interface that the caller
// is to use to communicate with the class object.
// * ppv - The address of a pointer variable that receives the interface
// pointer requested in riid. Upon successful return, *ppv contains the
// requested interface pointer. If an error occurs, the interface pointer
// is NULL.
//
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
{
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
if (IsEqualCLSID(CLSID_GcodeThumbnailProvider, rclsid))
{
hr = E_OUTOFMEMORY;
ClassFactory* pClassFactory = new ClassFactory();
if (pClassFactory)
{
hr = pClassFactory->QueryInterface(riid, ppv);
pClassFactory->Release();
}
}
return hr;
}
//
// FUNCTION: DllCanUnloadNow
//
// PURPOSE: Check if we can unload the component from the memory.
//
// NOTE: The component can be unloaded from the memory when its reference
// count is zero (i.e. nobody is still using the component).
//
STDAPI DllCanUnloadNow(void)
{
return g_cDllRef > 0 ? S_FALSE : S_OK;
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.220929.3" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220914.1" targetFramework="native" />
</packages>

View File

@ -0,0 +1,5 @@
// pch.cpp: source file corresponding to the pre-compiled header
#include "pch.h"
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.

View File

@ -0,0 +1,15 @@
// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.
#ifndef PCH_H
#define PCH_H
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
#include <winrt/base.h>
#endif //PCH_H

View File

@ -0,0 +1,13 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by AlwaysOnTopModuleInterface.rc
//////////////////////////////
// Non-localizable
#define FILE_DESCRIPTION "PowerToys Gcode Thumbnail Provider Module"
#define INTERNAL_NAME "PowerToys.GcodeThumbnailProviderCpp"
#define ORIGINAL_FILENAME "PowerToys.GcodeThumbnailProviderCpp.dll"
// Non-localizable
//////////////////////////////

View File

@ -1,71 +0,0 @@
// 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.Markdown
{
/// <summary>
/// Implementation of preview handler for markdown files.
/// </summary>
[Guid("45769bcc-e8fd-42d0-947e-02beef77a1f5")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class MarkdownPreviewHandler : FileBasedPreviewHandler, IDisposable
{
private MarkdownPreviewHandlerControl _markdownPreviewHandlerControl;
private bool disposedValue;
/// <summary>
/// Initializes a new instance of the <see cref="MarkdownPreviewHandler"/> class.
/// </summary>
public MarkdownPreviewHandler()
{
Initialize();
}
/// <inheritdoc />
public override void DoPreview()
{
_markdownPreviewHandlerControl.DoPreview(FilePath);
}
/// <inheritdoc />
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
{
PowerToysTelemetry.Log.WriteEvent(new Telemetry.Events.MarkdownFileHandlerLoaded());
_markdownPreviewHandlerControl = new MarkdownPreviewHandlerControl();
return _markdownPreviewHandlerControl;
}
/// <summary>
/// Disposes objects
/// </summary>
/// <param name="disposing">Is Disposing</param>
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
_markdownPreviewHandlerControl.Dispose();
}
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);
}
}
}

View File

@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<UseWindowsForms>true</UseWindowsForms>
<AssemblyTitle>PowerToys.MarkdownPreviewHandler</AssemblyTitle>
<AssemblyDescription>PowerToys MarkdownPreviewHandler</AssemblyDescription>
@ -12,12 +13,20 @@
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<RuntimeIdentifiers>win10-x64;win10-arm64</RuntimeIdentifiers>
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup>
<ProjectGuid>{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}</ProjectGuid>
<RootNamespace>Microsoft.PowerToys.PreviewHandler.Markdown</RootNamespace>
<EnableComHosting>true</EnableComHosting>
<AssemblyName>PowerToys.MarkdownPreviewHandler</AssemblyName>
</PropertyGroup>
@ -46,6 +55,7 @@
<PropertyGroup>
<!-- Disable missing comment warning. WinRT/C++ libraries added won't have comments on their reflections. -->
<NoWarn>$(NoWarn);1591</NoWarn>
<OutputType>WinExe</OutputType>
</PropertyGroup>
<ItemGroup>
@ -58,6 +68,7 @@
<ItemGroup>
<ProjectReference Include="..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
<ProjectReference Include="..\..\..\common\Common.UI\Common.UI.csproj" />
<ProjectReference Include="..\..\..\common\interop\PowerToys.Interop.vcxproj" />
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
<ProjectReference Include="..\common\PreviewHandlerCommon.csproj" />
</ItemGroup>

View File

@ -133,14 +133,11 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown
if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMarkdownPreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
{
// GPO is disabling this utility. Show an error message instead.
InvokeOnControlThread(() =>
{
_infoBarDisplayed = true;
_infoBar = GetTextBoxControl(Resources.GpoDisabledErrorText);
Resize += FormResized;
Controls.Add(_infoBar);
base.DoPreview(dataSource);
});
_infoBarDisplayed = true;
_infoBar = GetTextBoxControl(Resources.GpoDisabledErrorText);
Resize += FormResized;
Controls.Add(_infoBar);
base.DoPreview(dataSource);
return;
}
@ -153,7 +150,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown
{
if (!(dataSource is string filePath))
{
throw new ArgumentException($"{nameof(dataSource)} for {nameof(MarkdownPreviewHandler)} must be a string but was a '{typeof(T)}'");
throw new ArgumentException($"{nameof(dataSource)} for {nameof(MarkdownPreviewHandlerControl)} must be a string but was a '{typeof(T)}'");
}
string fileText = File.ReadAllText(filePath);
@ -174,80 +171,74 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown
Dock = DockStyle.Fill,
};
InvokeOnControlThread(() =>
{
var webView2Options = new CoreWebView2EnvironmentOptions("--block-new-web-contents");
ConfiguredTaskAwaitable<CoreWebView2Environment>.ConfiguredTaskAwaiter
var webView2Options = new CoreWebView2EnvironmentOptions("--block-new-web-contents");
ConfiguredTaskAwaitable<CoreWebView2Environment>.ConfiguredTaskAwaiter
webView2EnvironmentAwaiter = CoreWebView2Environment
.CreateAsync(userDataFolder: _webView2UserDataFolder, options: webView2Options)
.ConfigureAwait(true).GetAwaiter();
webView2EnvironmentAwaiter.OnCompleted(() =>
webView2EnvironmentAwaiter.OnCompleted(async () =>
{
try
{
InvokeOnControlThread(async () =>
_webView2Environment = webView2EnvironmentAwaiter.GetResult();
await _browser.EnsureCoreWebView2Async(_webView2Environment).ConfigureAwait(true);
_browser.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, AssemblyDirectory, CoreWebView2HostResourceAccessKind.Deny);
_browser.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false;
_browser.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
_browser.CoreWebView2.Settings.AreDevToolsEnabled = false;
_browser.CoreWebView2.Settings.AreHostObjectsAllowed = false;
_browser.CoreWebView2.Settings.IsGeneralAutofillEnabled = false;
_browser.CoreWebView2.Settings.IsPasswordAutosaveEnabled = false;
_browser.CoreWebView2.Settings.IsScriptEnabled = false;
_browser.CoreWebView2.Settings.IsWebMessageEnabled = false;
// Don't load any resources.
_browser.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
_browser.CoreWebView2.WebResourceRequested += (object sender, CoreWebView2WebResourceRequestedEventArgs e) =>
{
try
// Show local file we've saved with the markdown contents. Block all else.
if (new Uri(e.Request.Uri) != _localFileURI)
{
_webView2Environment = webView2EnvironmentAwaiter.GetResult();
await _browser.EnsureCoreWebView2Async(_webView2Environment).ConfigureAwait(true);
_browser.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, AssemblyDirectory, CoreWebView2HostResourceAccessKind.Deny);
_browser.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false;
_browser.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
_browser.CoreWebView2.Settings.AreDevToolsEnabled = false;
_browser.CoreWebView2.Settings.AreHostObjectsAllowed = false;
_browser.CoreWebView2.Settings.IsGeneralAutofillEnabled = false;
_browser.CoreWebView2.Settings.IsPasswordAutosaveEnabled = false;
_browser.CoreWebView2.Settings.IsScriptEnabled = false;
_browser.CoreWebView2.Settings.IsWebMessageEnabled = false;
// Don't load any resources.
_browser.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
_browser.CoreWebView2.WebResourceRequested += (object sender, CoreWebView2WebResourceRequestedEventArgs e) =>
{
// Show local file we've saved with the markdown contents. Block all else.
if (new Uri(e.Request.Uri) != _localFileURI)
{
e.Response = _browser.CoreWebView2.Environment.CreateWebResourceResponse(null, 403, "Forbidden", null);
}
};
// WebView2.NavigateToString() limitation
// See https://learn.microsoft.com/dotnet/api/microsoft.web.webview2.core.corewebview2.navigatetostring?view=webview2-dotnet-1.0.864.35#remarks
// While testing the limit, it turned out it is ~1.5MB, so to be on a safe side we go for 1.5m bytes
if (markdownHTML.Length > 1_500_000)
{
string filename = _webView2UserDataFolder + "\\" + Guid.NewGuid().ToString() + ".html";
File.WriteAllText(filename, markdownHTML);
_localFileURI = new Uri(filename);
_browser.Source = _localFileURI;
}
else
{
_browser.NavigateToString(markdownHTML);
}
Controls.Add(_browser);
_browser.NavigationStarting += async (object sender, CoreWebView2NavigationStartingEventArgs args) =>
{
if (args.Uri != null && args.Uri != _localFileURI?.ToString() && args.IsUserInitiated)
{
args.Cancel = true;
await Launcher.LaunchUriAsync(new Uri(args.Uri));
}
};
if (_infoBarDisplayed)
{
_infoBar = GetTextBoxControl(Resources.BlockedImageInfoText);
Resize += FormResized;
Controls.Add(_infoBar);
}
e.Response = _browser.CoreWebView2.Environment.CreateWebResourceResponse(null, 403, "Forbidden", null);
}
catch (NullReferenceException)
};
// WebView2.NavigateToString() limitation
// See https://learn.microsoft.com/dotnet/api/microsoft.web.webview2.core.corewebview2.navigatetostring?view=webview2-dotnet-1.0.864.35#remarks
// While testing the limit, it turned out it is ~1.5MB, so to be on a safe side we go for 1.5m bytes
if (markdownHTML.Length > 1_500_000)
{
string filename = _webView2UserDataFolder + "\\" + Guid.NewGuid().ToString() + ".html";
File.WriteAllText(filename, markdownHTML);
_localFileURI = new Uri(filename);
_browser.Source = _localFileURI;
}
else
{
_browser.NavigateToString(markdownHTML);
}
Controls.Add(_browser);
_browser.NavigationStarting += async (object sender, CoreWebView2NavigationStartingEventArgs args) =>
{
if (args.Uri != null && args.Uri != _localFileURI?.ToString() && args.IsUserInitiated)
{
args.Cancel = true;
await Launcher.LaunchUriAsync(new Uri(args.Uri));
}
});
});
};
if (_infoBarDisplayed)
{
_infoBar = GetTextBoxControl(Resources.BlockedImageInfoText);
Resize += FormResized;
Controls.Add(_infoBar);
}
}
catch (NullReferenceException)
{
}
});
PowerToysTelemetry.Log.WriteEvent(new MarkdownFilePreviewed());
@ -256,14 +247,11 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown
{
PowerToysTelemetry.Log.WriteEvent(new MarkdownFilePreviewError { Message = ex.Message });
InvokeOnControlThread(() =>
{
Controls.Clear();
_infoBarDisplayed = true;
_infoBar = GetTextBoxControl(Resources.MarkdownNotPreviewedError);
Resize += FormResized;
Controls.Add(_infoBar);
});
Controls.Clear();
_infoBarDisplayed = true;
_infoBar = GetTextBoxControl(Resources.MarkdownNotPreviewedError);
Resize += FormResized;
Controls.Add(_infoBar);
}
finally
{

View File

@ -0,0 +1,63 @@
// 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.
namespace Microsoft.PowerToys.PreviewHandler.Markdown
{
using System.Globalization;
using System.Windows.Threading;
using Common.UI;
using interop;
internal static class Program
{
private static CancellationTokenSource _tokenSource = new CancellationTokenSource();
private static MarkdownPreviewHandlerControl _previewHandlerControl;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Main(string[] args)
{
ApplicationConfiguration.Initialize();
if (args != null)
{
if (args.Length == 6)
{
string filePath = args[0];
int hwnd = Convert.ToInt32(args[1], 16);
Rectangle s = default(Rectangle);
int left = Convert.ToInt32(args[2], 10);
int right = Convert.ToInt32(args[3], 10);
int top = Convert.ToInt32(args[4], 10);
int bottom = Convert.ToInt32(args[5], 10);
_previewHandlerControl = new MarkdownPreviewHandlerControl();
_previewHandlerControl.SetWindow((IntPtr)hwnd, s);
_previewHandlerControl.DoPreview(filePath);
NativeEventWaiter.WaitForEventLoop(
Constants.MarkdownPreviewResizeEvent(),
() =>
{
Rectangle s = default(Rectangle);
_previewHandlerControl.SetRect(s);
},
Dispatcher.CurrentDispatcher,
_tokenSource.Token);
}
else
{
MessageBox.Show("Wrong number of args: " + args.Length.ToString(CultureInfo.InvariantCulture));
}
}
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
Application.Run();
}
}
}

View File

@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<PublishDir>$(PowerToysRoot)\$(Platform)\$(Configuration)\modules\FileExplorerPreview</PublishDir>
<RuntimeIdentifier>win10-$(Platform)</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun>False</PublishReadyToRun>
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>

View File

@ -0,0 +1,84 @@
#include "pch.h"
#include "ClassFactory.h"
#include "MarkdownPreviewHandler.h"
#include <new>
#include <Shlwapi.h>
extern long g_cDllRef;
ClassFactory::ClassFactory() :
m_cRef(1)
{
InterlockedIncrement(&g_cDllRef);
}
ClassFactory::~ClassFactory()
{
InterlockedDecrement(&g_cDllRef);
}
//
// IUnknown
//
IFACEMETHODIMP ClassFactory::QueryInterface(REFIID riid, void **ppv)
{
static const QITAB qit[] = {
QITABENT(ClassFactory, IClassFactory),
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG) ClassFactory::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
IFACEMETHODIMP_(ULONG) ClassFactory::Release()
{
ULONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
}
return cRef;
}
//
// IClassFactory
//
IFACEMETHODIMP ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
HRESULT hr = CLASS_E_NOAGGREGATION;
if (pUnkOuter == NULL)
{
hr = E_OUTOFMEMORY;
MarkdownPreviewHandler* pExt = new (std::nothrow) MarkdownPreviewHandler();
if (pExt)
{
hr = pExt->QueryInterface(riid, ppv);
pExt->Release();
}
}
return hr;
}
IFACEMETHODIMP ClassFactory::LockServer(BOOL fLock)
{
if (fLock)
{
InterlockedIncrement(&g_cDllRef);
}
else
{
InterlockedDecrement(&g_cDllRef);
}
return S_OK;
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <Unknwn.h>
class ClassFactory : public IClassFactory
{
public:
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv);
IFACEMETHODIMP_(ULONG) AddRef();
IFACEMETHODIMP_(ULONG) Release();
// IClassFactory
IFACEMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppv);
IFACEMETHODIMP LockServer(BOOL fLock);
ClassFactory();
protected:
~ClassFactory();
private:
long m_cRef;
};

View File

@ -0,0 +1,3 @@
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE

View File

@ -0,0 +1,263 @@
#include "pch.h"
#include "MarkdownPreviewHandler.h"
#include "Generated Files/resource.h"
#include <shellapi.h>
#include <Shlwapi.h>
#include <string>
#include <common/interop/shared_constants.h>
#include <common/logger/logger.h>
#include <common/SettingsAPI/settings_helpers.h>
#include <common/utils/process_path.h>
extern HINSTANCE g_hInst;
extern long g_cDllRef;
MarkdownPreviewHandler::MarkdownPreviewHandler() :
m_cRef(1), m_hwndParent(NULL), m_rcParent(), m_punkSite(NULL), m_process(NULL)
{
m_resizeEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::MARKDOWN_PREVIEW_RESIZE_EVENT);
std::filesystem::path logFilePath(PTSettingsHelper::get_local_low_folder_location());
logFilePath.append(LogSettings::mdPrevLogPath);
Logger::init(LogSettings::mdPrevLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
InterlockedIncrement(&g_cDllRef);
}
MarkdownPreviewHandler::~MarkdownPreviewHandler()
{
InterlockedDecrement(&g_cDllRef);
}
#pragma region IUnknown
IFACEMETHODIMP MarkdownPreviewHandler::QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] = {
QITABENT(MarkdownPreviewHandler, IPreviewHandler),
QITABENT(MarkdownPreviewHandler, IInitializeWithFile),
QITABENT(MarkdownPreviewHandler, IPreviewHandlerVisuals),
QITABENT(MarkdownPreviewHandler, IOleWindow),
QITABENT(MarkdownPreviewHandler, IObjectWithSite),
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG)
MarkdownPreviewHandler::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
IFACEMETHODIMP_(ULONG)
MarkdownPreviewHandler::Release()
{
ULONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
}
return cRef;
}
#pragma endregion
#pragma region IInitializationWithFile
IFACEMETHODIMP MarkdownPreviewHandler::Initialize(LPCWSTR pszFilePath, DWORD grfMode)
{
m_filePath = pszFilePath;
return S_OK;
}
#pragma endregion
#pragma region IPreviewHandler
IFACEMETHODIMP MarkdownPreviewHandler::SetWindow(HWND hwnd, const RECT* prc)
{
if (hwnd && prc)
{
m_hwndParent = hwnd;
m_rcParent = *prc;
}
return S_OK;
}
IFACEMETHODIMP MarkdownPreviewHandler::SetFocus()
{
return S_OK;
}
IFACEMETHODIMP MarkdownPreviewHandler::QueryFocus(HWND* phwnd)
{
HRESULT hr = E_INVALIDARG;
if (phwnd)
{
*phwnd = ::GetFocus();
if (*phwnd)
{
hr = S_OK;
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
return hr;
}
IFACEMETHODIMP MarkdownPreviewHandler::TranslateAccelerator(MSG* pmsg)
{
HRESULT hr = S_FALSE;
IPreviewHandlerFrame* pFrame = NULL;
if (m_punkSite && SUCCEEDED(m_punkSite->QueryInterface(&pFrame)))
{
hr = pFrame->TranslateAccelerator(pmsg);
pFrame->Release();
}
return hr;
}
IFACEMETHODIMP MarkdownPreviewHandler::SetRect(const RECT* prc)
{
HRESULT hr = E_INVALIDARG;
if (prc != NULL)
{
if (!m_resizeEvent)
{
Logger::error(L"Failed to create resize event for MDPreviewHandler");
}
else
{
if (m_rcParent.right != prc->right || m_rcParent.left != prc->left || m_rcParent.top != prc->top || m_rcParent.bottom != prc->bottom)
{
if (!SetEvent(m_resizeEvent))
{
Logger::error(L"Failed to signal resize event for MDPreviewHandler");
}
}
}
m_rcParent = *prc;
hr = S_OK;
}
return hr;
}
IFACEMETHODIMP MarkdownPreviewHandler::DoPreview()
{
try
{
Logger::info(L"Starting MarkdownPreviewHandler.exe");
STARTUPINFO info = { sizeof(info) };
std::wstring cmdLine{ L"\"" + m_filePath + L"\"" };
cmdLine += L" ";
std::wostringstream ss;
ss << std::hex << m_hwndParent;
cmdLine += ss.str();
cmdLine += L" ";
cmdLine += std::to_wstring(m_rcParent.left);
cmdLine += L" ";
cmdLine += std::to_wstring(m_rcParent.right);
cmdLine += L" ";
cmdLine += std::to_wstring(m_rcParent.top);
cmdLine += L" ";
cmdLine += std::to_wstring(m_rcParent.bottom);
std::wstring appPath = get_module_folderpath(g_hInst) + L"\\PowerToys.MarkdownPreviewHandler.exe";
SHELLEXECUTEINFO sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = appPath.c_str();
sei.lpParameters = cmdLine.c_str();
sei.nShow = SW_SHOWDEFAULT;
ShellExecuteEx(&sei);
m_process = sei.hProcess;
}
catch (std::exception& e)
{
std::wstring errorMessage = std::wstring{ winrt::to_hstring(e.what()) };
Logger::error(L"Failed to start MarkdownPreviewHandler.exe. Error: {}", errorMessage);
}
return S_OK;
}
IFACEMETHODIMP MarkdownPreviewHandler::Unload()
{
Logger::info(L"Unload and terminate .exe");
TerminateProcess(m_process, 0);
return S_OK;
}
#pragma endregion
#pragma region IPreviewHandlerVisuals
IFACEMETHODIMP MarkdownPreviewHandler::SetBackgroundColor(COLORREF color)
{
return S_OK;
}
IFACEMETHODIMP MarkdownPreviewHandler::SetFont(const LOGFONTW* plf)
{
return S_OK;
}
IFACEMETHODIMP MarkdownPreviewHandler::SetTextColor(COLORREF color)
{
return S_OK;
}
#pragma endregion
#pragma region IOleWindow
IFACEMETHODIMP MarkdownPreviewHandler::GetWindow(HWND* phwnd)
{
HRESULT hr = E_INVALIDARG;
if (phwnd)
{
*phwnd = m_hwndParent;
hr = S_OK;
}
return hr;
}
IFACEMETHODIMP MarkdownPreviewHandler::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
}
#pragma endregion
#pragma region IObjectWithSite
IFACEMETHODIMP MarkdownPreviewHandler::SetSite(IUnknown* punkSite)
{
if (m_punkSite)
{
m_punkSite->Release();
m_punkSite = NULL;
}
return punkSite ? punkSite->QueryInterface(&m_punkSite) : S_OK;
}
IFACEMETHODIMP MarkdownPreviewHandler::GetSite(REFIID riid, void** ppv)
{
*ppv = NULL;
return m_punkSite ? m_punkSite->QueryInterface(riid, ppv) : E_FAIL;
}
#pragma endregion
#pragma region Helper Functions
#pragma endregion

View File

@ -0,0 +1,69 @@
#pragma once
#include "pch.h"
#include <filesystem>
#include <ShlObj.h>
#include <string>
class MarkdownPreviewHandler :
public IInitializeWithFile,
public IPreviewHandler,
public IPreviewHandlerVisuals,
public IOleWindow,
public IObjectWithSite
{
public:
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv);
IFACEMETHODIMP_(ULONG) AddRef();
IFACEMETHODIMP_(ULONG) Release();
// IInitializeWithFile
IFACEMETHODIMP Initialize(LPCWSTR pszFilePath, DWORD grfMode);
// IPreviewHandler
IFACEMETHODIMP SetWindow(HWND hwnd, const RECT* prc);
IFACEMETHODIMP SetFocus();
IFACEMETHODIMP QueryFocus(HWND* phwnd);
IFACEMETHODIMP TranslateAccelerator(MSG* pmsg);
IFACEMETHODIMP SetRect(const RECT* prc);
IFACEMETHODIMP DoPreview();
IFACEMETHODIMP Unload();
// IPreviewHandlerVisuals
IFACEMETHODIMP SetBackgroundColor(COLORREF color);
IFACEMETHODIMP SetFont(const LOGFONTW* plf);
IFACEMETHODIMP SetTextColor(COLORREF color);
// IOleWindow
IFACEMETHODIMP GetWindow(HWND* phwnd);
IFACEMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
// IObjectWithSite
IFACEMETHODIMP SetSite(IUnknown* punkSite);
IFACEMETHODIMP GetSite(REFIID riid, void** ppv);
MarkdownPreviewHandler();
protected:
~MarkdownPreviewHandler();
private:
// Reference count of component.
long m_cRef;
// Provided during initialization.
std::wstring m_filePath;
// Parent window that hosts the previewer window.
// Note: do NOT DestroyWindow this.
HWND m_hwndParent;
// Bounding rect of the parent window.
RECT m_rcParent;
// Site pointer from host, used to get IPreviewHandlerFrame.
IUnknown* m_punkSite;
HANDLE m_process;
HANDLE m_resizeEvent;
};

View File

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" />
<Target Name="GenerateResourceFiles" BeforeTargets="PrepareForBuild">
<Exec Command="powershell -NonInteractive -executionpolicy Unrestricted $(SolutionDir)tools\build\convert-resx-to-rc.ps1 $(MSBuildThisFileDirectory) resource.base.h resource.h markdownpreviewhandler.base.rc markdownpreviewhandler.rc" />
</Target>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{ed9a1ac6-aeb0-4569-a6e9-e1696182b545}</ProjectGuid>
<RootNamespace>MarkdownPreviewHandlerCpp</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</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">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\</OutDir>
<CopyCppRuntimeToOutputDir>true</CopyCppRuntimeToOutputDir>
</PropertyGroup>
<PropertyGroup>
<TargetName>PowerToys.$(ProjectName)</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;MARKDOWNPREVIEWHANDLERCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>../../..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>GlobalExportFunctions.def</ModuleDefinitionFile>
<AdditionalDependencies>Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;MARKDOWNPREVIEWHANDLERCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>../../..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>GlobalExportFunctions.def</ModuleDefinitionFile>
<AdditionalDependencies>Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="ClassFactory.h" />
<ClInclude Include="MarkdownPreviewHandler.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="resource.base.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ClassFactory.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="MarkdownPreviewHandler.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="GlobalExportFunctions.def" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Generated Files/markdownpreviewhandler.rc" />
<None Include="markdownpreviewhandler.base.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\common\SettingsAPI\SettingsAPI.vcxproj">
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Resources.resx" />
</ItemGroup>
<Import Project="..\..\..\..\deps\spdlog.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ClassFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MarkdownPreviewHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.base.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ClassFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MarkdownPreviewHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="GlobalExportFunctions.def">
<Filter>Source Files</Filter>
</None>
<None Include="packages.config" />
<None Include="markdownpreviewhandler.base.rc">
<Filter>Resource Files</Filter>
</None>
<None Include="Resources.resx">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Generated Files/markdownpreviewhandler.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,113 @@
<?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">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized CLR Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the CLR Framework object]
</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 CLR 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.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: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" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" 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" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="GpoDisabledErrorText" xml:space="preserve">
<value>Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator.</value>
</data>
</root>

View File

@ -0,0 +1,74 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include "ClassFactory.h"
HINSTANCE g_hInst = NULL;
long g_cDllRef = 0;
// {60789D87-9C3C-44AF-B18C-3DE2C2820ED3}
static const GUID CLSID_MarkdownPreviewHandler = { 0x60789d87, 0x9c3c, 0x44af, { 0xb1, 0x8c, 0x3d, 0xe2, 0xc2, 0x82, 0xe, 0xd3 } };
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hInst = hModule;
DisableThreadLibraryCalls(hModule);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//
// FUNCTION: DllGetClassObject
//
// PURPOSE: Create the class factory and query to the specific interface.
//
// PARAMETERS:
// * rclsid - The CLSID that will associate the correct data and code.
// * riid - A reference to the identifier of the interface that the caller
// is to use to communicate with the class object.
// * ppv - The address of a pointer variable that receives the interface
// pointer requested in riid. Upon successful return, *ppv contains the
// requested interface pointer. If an error occurs, the interface pointer
// is NULL.
//
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
{
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
if (IsEqualCLSID(CLSID_MarkdownPreviewHandler, rclsid))
{
hr = E_OUTOFMEMORY;
ClassFactory* pClassFactory = new ClassFactory();
if (pClassFactory)
{
hr = pClassFactory->QueryInterface(riid, ppv);
pClassFactory->Release();
}
}
return hr;
}
//
// FUNCTION: DllCanUnloadNow
//
// PURPOSE: Check if we can unload the component from the memory.
//
// NOTE: The component can be unloaded from the memory when its reference
// count is zero (i.e. nobody is still using the component).
//
STDAPI DllCanUnloadNow(void)
{
return g_cDllRef > 0 ? S_FALSE : S_OK;
}

View File

@ -0,0 +1,46 @@
#include <windows.h>
#include "resource.h"
#include "../../../../common/version/version.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
1 VERSIONINFO
FILEVERSION FILE_VERSION
PRODUCTVERSION PRODUCT_VERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
BEGIN
VALUE "CompanyName", COMPANY_NAME
VALUE "FileDescription", FILE_DESCRIPTION
VALUE "FileVersion", FILE_VERSION_STRING
VALUE "InternalName", INTERNAL_NAME
VALUE "LegalCopyright", COPYRIGHT_NOTE
VALUE "OriginalFilename", ORIGINAL_FILENAME
VALUE "ProductName", PRODUCT_NAME
VALUE "ProductVersion", PRODUCT_VERSION_STRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
END
END

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.220929.3" targetFramework="native" />
</packages>

View File

@ -0,0 +1,5 @@
// pch.cpp: source file corresponding to the pre-compiled header
#include "pch.h"
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.

View File

@ -0,0 +1,14 @@
// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.
#ifndef PCH_H
#define PCH_H
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
#endif //PCH_H

View File

@ -0,0 +1,13 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by powerpreview.rc
//////////////////////////////
// Non-localizable
#define FILE_DESCRIPTION "PowerToys Markdown Preview Handler"
#define INTERNAL_NAME "PowerToys.MarkdownPreviewHandler"
#define ORIGINAL_FILENAME "PowerToys.MarkdownPreviewHandlerCpp.dll"
// Non-localizable
//////////////////////////////

View File

@ -0,0 +1,14 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by markdownpreviewhandler.base.rc
// 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

@ -1,72 +0,0 @@
// 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.
namespace Microsoft.PowerToys.PreviewHandler.Monaco
{
using System;
using System.Runtime.InteropServices;
using Common;
/// <summary>
/// Implementation of preview handler for files with source code.
/// </summary>
[Guid("afbd5a44-2520-4ae0-9224-6cfce8fe4400")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class MonacoPreviewHandler : FileBasedPreviewHandler, IDisposable
{
private MonacoPreviewHandlerControl _monacoPreviewHandlerControl;
private bool _disposedValue;
/// <summary>
/// Initializes a new instance of the <see cref="MonacoPreviewHandler"/> class.
/// </summary>
public MonacoPreviewHandler()
{
this.Initialize();
}
/// <inheritdoc />
[STAThread]
public override void DoPreview()
{
_monacoPreviewHandlerControl.DoPreview(FilePath);
}
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
{
_monacoPreviewHandlerControl = new MonacoPreviewHandlerControl();
return _monacoPreviewHandlerControl;
}
/// <summary>
/// Disposes objects
/// </summary>
/// <param name="disposing">Is Disposing</param>
[STAThread]
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
_monacoPreviewHandlerControl.Dispose();
}
_disposedValue = true;
this.Unload();
}
}
/// <inheritdoc />
[STAThread]
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}

View File

@ -1,5 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<UseWindowsForms>true</UseWindowsForms>
<AssemblyTitle>PowerToys.MonacoPreviewHandler</AssemblyTitle>
<AssemblyDescription>PowerToys MonacoPreviewHandler</AssemblyDescription>
<Description>PowerToys MonacoPreviewHandler</Description>
@ -9,14 +11,22 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<RuntimeIdentifiers>win10-x64;win10-arm64</RuntimeIdentifiers>
<SelfContained>true</SelfContained>
</PropertyGroup>
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
<PropertyGroup Condition="'$(Platform)'=='x64'">
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
</PropertyGroup>
<Import Project="..\..\..\Version.props" />
<PropertyGroup>
<RootNamespace>Microsoft.PowerToys.PreviewHandler.Monaco</RootNamespace>
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<EnableComHosting>true</EnableComHosting>
<AssemblyName>PowerToys.MonacoPreviewHandler</AssemblyName>
</PropertyGroup>
@ -35,6 +45,7 @@
<PropertyGroup>
<!-- Disable missing comment warning. WinRT/C++ libraries added won't have comments on their reflections. -->
<NoWarn>$(NoWarn);1591</NoWarn>
<OutputType>WinExe</OutputType>
</PropertyGroup>
<ItemGroup>

View File

@ -107,13 +107,10 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMonacoPreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
{
// GPO is disabling this utility. Show an error message instead.
InvokeOnControlThread(() =>
{
_infoBarAdded = true;
AddTextBoxControl(Properties.Resources.GpoDisabledErrorText);
Resize += FormResized;
base.DoPreview(dataSource);
});
_infoBarAdded = true;
AddTextBoxControl(Properties.Resources.GpoDisabledErrorText);
Resize += FormResized;
base.DoPreview(dataSource);
return;
}
@ -132,7 +129,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
// Checks if dataSource is a string
if (!(dataSource is string filePath))
{
throw new ArgumentException($"{nameof(dataSource)} for {nameof(MonacoPreviewHandler)} must be a string but was a '{typeof(T)}'");
throw new ArgumentException($"{nameof(dataSource)} for {nameof(MonacoPreviewHandlerControl)} must be a string but was a '{typeof(T)}'");
}
// Check if the file is too big.
@ -145,103 +142,94 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
try
{
InvokeOnControlThread(() =>
Logger.LogInfo("Create WebView2 environment");
ConfiguredTaskAwaitable<CoreWebView2Environment>.ConfiguredTaskAwaiter
webView2EnvironmentAwaiter = CoreWebView2Environment
.CreateAsync(userDataFolder: System.Environment.GetEnvironmentVariable("USERPROFILE") +
"\\AppData\\LocalLow\\Microsoft\\PowerToys\\MonacoPreview-Temp")
.ConfigureAwait(true).GetAwaiter();
webView2EnvironmentAwaiter.OnCompleted(async () =>
{
Logger.LogInfo("Create WebView2 environment");
ConfiguredTaskAwaitable<CoreWebView2Environment>.ConfiguredTaskAwaiter
webView2EnvironmentAwaiter = CoreWebView2Environment
.CreateAsync(userDataFolder: System.Environment.GetEnvironmentVariable("USERPROFILE") +
"\\AppData\\LocalLow\\Microsoft\\PowerToys\\MonacoPreview-Temp")
.ConfigureAwait(true).GetAwaiter();
webView2EnvironmentAwaiter.OnCompleted(() =>
_loadingBar.Value = 60;
this.Update();
try
{
_loadingBar.Value = 60;
this.Update();
InvokeOnControlThread(async () =>
if (CoreWebView2Environment.GetAvailableBrowserVersionString() == null)
{
try
{
if (CoreWebView2Environment.GetAvailableBrowserVersionString() == null)
{
throw new WebView2RuntimeNotFoundException();
}
throw new WebView2RuntimeNotFoundException();
}
_webView2Environment = webView2EnvironmentAwaiter.GetResult();
_webView2Environment = webView2EnvironmentAwaiter.GetResult();
_loadingBar.Value = 70;
this.Update();
_loadingBar.Value = 70;
this.Update();
// Initialize WebView
try
{
await _webView.EnsureCoreWebView2Async(_webView2Environment).ConfigureAwait(true);
// Initialize WebView
try
{
await _webView.EnsureCoreWebView2Async(_webView2Environment).ConfigureAwait(true);
// Wait until html is loaded
initializeIndexFileAndSelectedFileTask.Wait();
// Wait until html is loaded
initializeIndexFileAndSelectedFileTask.Wait();
_webView.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, Settings.AssemblyDirectory, CoreWebView2HostResourceAccessKind.Allow);
_webView.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, Settings.AssemblyDirectory, CoreWebView2HostResourceAccessKind.Allow);
Logger.LogInfo("Navigates to string of HTML file");
Logger.LogInfo("Navigates to string of HTML file");
_webView.NavigateToString(_html);
_webView.NavigationCompleted += WebView2Init;
_webView.Height = this.Height;
_webView.Width = this.Width;
Controls.Add(_webView);
_webView.SendToBack();
_loadingBar.Value = 100;
this.Update();
}
catch (NullReferenceException e)
{
Logger.LogError("NullReferenceException catched. Skipping exception.", e);
}
}
catch (WebView2RuntimeNotFoundException e)
{
Logger.LogWarning("WebView2 was not found:");
Logger.LogWarning(e.Message);
Controls.Remove(_loading);
Controls.Remove(_loadingBar);
Controls.Remove(_loadingBackground);
_webView.NavigateToString(_html);
_webView.NavigationCompleted += WebView2Init;
_webView.Height = this.Height;
_webView.Width = this.Width;
Controls.Add(_webView);
_webView.SendToBack();
_loadingBar.Value = 100;
this.Update();
}
catch (NullReferenceException e)
{
Logger.LogError("NullReferenceException catched. Skipping exception.", e);
}
}
catch (WebView2RuntimeNotFoundException e)
{
Logger.LogWarning("WebView2 was not found:");
Logger.LogWarning(e.Message);
Controls.Remove(_loading);
Controls.Remove(_loadingBar);
Controls.Remove(_loadingBackground);
// WebView2 not installed message
Label errorMessage = new Label();
errorMessage.Text = Resources.WebView2_Not_Installed_Message;
errorMessage.Width = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Width + 10;
errorMessage.Height = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Height;
Controls.Add(errorMessage);
// WebView2 not installed message
Label errorMessage = new Label();
errorMessage.Text = Resources.WebView2_Not_Installed_Message;
errorMessage.Width = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Width + 10;
errorMessage.Height = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Height;
Controls.Add(errorMessage);
// Download Link
Label downloadLink = new LinkLabel();
downloadLink.Text = Resources.Download_WebView2;
downloadLink.Click += DownloadLink_Click;
downloadLink.Top = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Height + 10;
downloadLink.Width = TextRenderer.MeasureText(Resources.Download_WebView2, errorMessage.Font).Width + 10;
downloadLink.Height = TextRenderer.MeasureText(Resources.Download_WebView2, errorMessage.Font).Height;
Controls.Add(downloadLink);
}
});
});
// Download Link
Label downloadLink = new LinkLabel();
downloadLink.Text = Resources.Download_WebView2;
downloadLink.Click += DownloadLink_Click;
downloadLink.Top = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Height + 10;
downloadLink.Width = TextRenderer.MeasureText(Resources.Download_WebView2, errorMessage.Font).Width + 10;
downloadLink.Height = TextRenderer.MeasureText(Resources.Download_WebView2, errorMessage.Font).Height;
Controls.Add(downloadLink);
}
});
}
catch (Exception e)
{
InvokeOnControlThread(() =>
{
Controls.Remove(_loading);
Controls.Remove(_loadingBar);
Controls.Remove(_loadingBackground);
Label text = new Label();
text.Text = Resources.Exception_Occurred;
text.Text += e.Message;
text.Text += "\n" + e.Source;
text.Text += "\n" + e.StackTrace;
text.Width = 500;
text.Height = 10000;
Controls.Add(text);
Logger.LogError(e.Message);
});
Controls.Remove(_loading);
Controls.Remove(_loadingBar);
Controls.Remove(_loadingBackground);
Label text = new Label();
text.Text = Resources.Exception_Occurred;
text.Text += e.Message;
text.Text += "\n" + e.Source;
text.Text += "\n" + e.StackTrace;
text.Width = 500;
text.Height = 10000;
Controls.Add(text);
Logger.LogError(e.Message);
}
this.Resize += FormResize;
@ -249,18 +237,16 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
else
{
Logger.LogInfo("File is too big to display. Showing error message");
InvokeOnControlThread(() =>
{
Controls.Remove(_loading);
_loadingBar.Dispose();
Controls.Remove(_loadingBar);
Controls.Remove(_loadingBackground);
Label errorMessage = new Label();
errorMessage.Text = Resources.Max_File_Size_Error.Replace("%1", (_settings.MaxFileSize / 1000).ToString(CultureInfo.CurrentCulture), StringComparison.InvariantCulture);
errorMessage.Width = 500;
errorMessage.Height = 50;
Controls.Add(errorMessage);
});
Controls.Remove(_loading);
_loadingBar.Dispose();
Controls.Remove(_loadingBar);
Controls.Remove(_loadingBackground);
Label errorMessage = new Label();
errorMessage.Text = Resources.Max_File_Size_Error.Replace("%1", (_settings.MaxFileSize / 1000).ToString(CultureInfo.CurrentCulture), StringComparison.InvariantCulture);
errorMessage.Width = 500;
errorMessage.Height = 50;
Controls.Add(errorMessage);
}
}
@ -350,46 +336,41 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
private void SetBackground()
{
Logger.LogTrace();
InvokeOnControlThread(() =>
{
this.BackColor = Settings.BackgroundColor;
});
this.BackColor = Settings.BackgroundColor;
}
private void InitializeLoadingScreen()
{
Logger.LogTrace();
InvokeOnControlThread(() =>
{
_loadingBackground = new Label();
_loadingBackground.BackColor = Settings.BackgroundColor;
_loadingBackground.Width = this.Width;
_loadingBackground.Height = this.Height;
Controls.Add(_loadingBackground);
_loadingBackground.BringToFront();
_loadingBackground = new Label();
_loadingBackground.BackColor = Settings.BackgroundColor;
_loadingBackground.Width = this.Width;
_loadingBackground.Height = this.Height;
Controls.Add(_loadingBackground);
_loadingBackground.BringToFront();
_loadingBar = new ProgressBar();
_loadingBar.Width = this.Width - 10;
_loadingBar.Location = new Point(5, this.Height / 2);
_loadingBar.Maximum = 100;
_loadingBar.Value = 10;
Controls.Add(_loadingBar);
_loadingBar = new ProgressBar();
_loadingBar.Width = this.Width - 10;
_loadingBar.Location = new Point(5, this.Height / 2);
_loadingBar.Maximum = 100;
_loadingBar.Value = 10;
Controls.Add(_loadingBar);
_loading = new Label();
_loading.Text = Resources.Loading_Screen_Message;
_loading.Width = this.Width;
_loading.Height = 45;
_loading.Location = new Point(0, _loadingBar.Location.Y - _loading.Height);
_loading.TextAlign = ContentAlignment.TopCenter;
_loading.Font = new Font("MS Sans Serif", 16, FontStyle.Bold);
_loading.ForeColor = Settings.TextColor;
Controls.Add(_loading);
_loading = new Label();
_loading.Text = Resources.Loading_Screen_Message;
_loading.Width = this.Width;
_loading.Height = 45;
_loading.Location = new Point(0, _loadingBar.Location.Y - _loading.Height);
_loading.TextAlign = ContentAlignment.TopCenter;
_loading.Font = new Font("MS Sans Serif", 16, FontStyle.Bold);
_loading.ForeColor = Settings.TextColor;
Controls.Add(_loading);
_loading.BringToFront();
_loadingBar.BringToFront();
_loading.BringToFront();
_loadingBar.BringToFront();
this.Update();
this.Update();
});
Logger.LogInfo("Loading screen initialized");
}

View File

@ -0,0 +1,63 @@
// 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.
namespace Microsoft.PowerToys.PreviewHandler.Monaco
{
using System.Globalization;
using System.Windows.Threading;
using Common.UI;
using interop;
internal static class Program
{
private static CancellationTokenSource _tokenSource = new CancellationTokenSource();
private static MonacoPreviewHandlerControl _previewHandlerControl;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Main(string[] args)
{
ApplicationConfiguration.Initialize();
if (args != null)
{
if (args.Length == 6)
{
string filePath = args[0];
int hwnd = Convert.ToInt32(args[1], 16);
Rectangle s = default(Rectangle);
int left = Convert.ToInt32(args[2], 10);
int right = Convert.ToInt32(args[3], 10);
int top = Convert.ToInt32(args[4], 10);
int bottom = Convert.ToInt32(args[5], 10);
_previewHandlerControl = new MonacoPreviewHandlerControl();
_previewHandlerControl.SetWindow((IntPtr)hwnd, s);
_previewHandlerControl.DoPreview(filePath);
NativeEventWaiter.WaitForEventLoop(
Constants.DevFilesPreviewResizeEvent(),
() =>
{
Rectangle s = default(Rectangle);
_previewHandlerControl.SetRect(s);
},
Dispatcher.CurrentDispatcher,
_tokenSource.Token);
}
else
{
MessageBox.Show("Wrong number of args: " + args.Length.ToString(CultureInfo.InvariantCulture));
}
}
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
Application.Run();
}
}
}

View File

@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<PublishDir>$(PowerToysRoot)\$(Platform)\$(Configuration)\modules\FileExplorerPreview</PublishDir>
<RuntimeIdentifier>win10-$(Platform)</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun>False</PublishReadyToRun>
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>

View File

@ -0,0 +1,84 @@
#include "pch.h"
#include "ClassFactory.h"
#include "MonacoPreviewHandler.h"
#include <new>
#include <Shlwapi.h>
extern long g_cDllRef;
ClassFactory::ClassFactory() :
m_cRef(1)
{
InterlockedIncrement(&g_cDllRef);
}
ClassFactory::~ClassFactory()
{
InterlockedDecrement(&g_cDllRef);
}
//
// IUnknown
//
IFACEMETHODIMP ClassFactory::QueryInterface(REFIID riid, void **ppv)
{
static const QITAB qit[] = {
QITABENT(ClassFactory, IClassFactory),
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG) ClassFactory::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
IFACEMETHODIMP_(ULONG) ClassFactory::Release()
{
ULONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
}
return cRef;
}
//
// IClassFactory
//
IFACEMETHODIMP ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
{
HRESULT hr = CLASS_E_NOAGGREGATION;
if (pUnkOuter == NULL)
{
hr = E_OUTOFMEMORY;
MonacoPreviewHandler* pExt = new (std::nothrow) MonacoPreviewHandler();
if (pExt)
{
hr = pExt->QueryInterface(riid, ppv);
pExt->Release();
}
}
return hr;
}
IFACEMETHODIMP ClassFactory::LockServer(BOOL fLock)
{
if (fLock)
{
InterlockedIncrement(&g_cDllRef);
}
else
{
InterlockedDecrement(&g_cDllRef);
}
return S_OK;
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <Unknwn.h>
class ClassFactory : public IClassFactory
{
public:
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv);
IFACEMETHODIMP_(ULONG) AddRef();
IFACEMETHODIMP_(ULONG) Release();
// IClassFactory
IFACEMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppv);
IFACEMETHODIMP LockServer(BOOL fLock);
ClassFactory();
protected:
~ClassFactory();
private:
long m_cRef;
};

View File

@ -0,0 +1,3 @@
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE

View File

@ -0,0 +1,262 @@
#include "pch.h"
#include "MonacoPreviewHandler.h"
#include <shellapi.h>
#include <Shlwapi.h>
#include <string>
#include <common/interop/shared_constants.h>
#include <common/logger/logger.h>
#include <common/SettingsAPI/settings_helpers.h>
#include <common/utils/process_path.h>
extern HINSTANCE g_hInst;
extern long g_cDllRef;
MonacoPreviewHandler::MonacoPreviewHandler() :
m_cRef(1), m_hwndParent(NULL), m_rcParent(), m_punkSite(NULL), m_process(NULL)
{
m_resizeEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::DEV_FILES_PREVIEW_RESIZE_EVENT);
std::filesystem::path logFilePath(PTSettingsHelper::get_local_low_folder_location());
logFilePath.append(LogSettings::monacoPrevLogPath);
Logger::init(LogSettings::monacoPrevLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
InterlockedIncrement(&g_cDllRef);
}
MonacoPreviewHandler::~MonacoPreviewHandler()
{
InterlockedDecrement(&g_cDllRef);
}
#pragma region IUnknown
IFACEMETHODIMP MonacoPreviewHandler::QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] = {
QITABENT(MonacoPreviewHandler, IPreviewHandler),
QITABENT(MonacoPreviewHandler, IInitializeWithFile),
QITABENT(MonacoPreviewHandler, IPreviewHandlerVisuals),
QITABENT(MonacoPreviewHandler, IOleWindow),
QITABENT(MonacoPreviewHandler, IObjectWithSite),
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG)
MonacoPreviewHandler::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
IFACEMETHODIMP_(ULONG)
MonacoPreviewHandler::Release()
{
ULONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
}
return cRef;
}
#pragma endregion
#pragma region IInitializationWithFile
IFACEMETHODIMP MonacoPreviewHandler::Initialize(LPCWSTR pszFilePath, DWORD grfMode)
{
m_filePath = pszFilePath;
return S_OK;
}
#pragma endregion
#pragma region IPreviewHandler
IFACEMETHODIMP MonacoPreviewHandler::SetWindow(HWND hwnd, const RECT* prc)
{
if (hwnd && prc)
{
m_hwndParent = hwnd;
m_rcParent = *prc;
}
return S_OK;
}
IFACEMETHODIMP MonacoPreviewHandler::SetFocus()
{
return S_OK;
}
IFACEMETHODIMP MonacoPreviewHandler::QueryFocus(HWND* phwnd)
{
HRESULT hr = E_INVALIDARG;
if (phwnd)
{
*phwnd = ::GetFocus();
if (*phwnd)
{
hr = S_OK;
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
return hr;
}
IFACEMETHODIMP MonacoPreviewHandler::TranslateAccelerator(MSG* pmsg)
{
HRESULT hr = S_FALSE;
IPreviewHandlerFrame* pFrame = NULL;
if (m_punkSite && SUCCEEDED(m_punkSite->QueryInterface(&pFrame)))
{
hr = pFrame->TranslateAccelerator(pmsg);
pFrame->Release();
}
return hr;
}
IFACEMETHODIMP MonacoPreviewHandler::SetRect(const RECT* prc)
{
HRESULT hr = E_INVALIDARG;
if (prc != NULL)
{
if (!m_resizeEvent)
{
Logger::error(L"Failed to create resize event for MonacoPreviewHandler");
}
else
{
if (m_rcParent.right != prc->right || m_rcParent.left != prc->left || m_rcParent.top != prc->top || m_rcParent.bottom != prc->bottom)
{
if (!SetEvent(m_resizeEvent))
{
Logger::error(L"Failed to signal resize event for MonacoPreviewHandler");
}
}
}
m_rcParent = *prc;
hr = S_OK;
}
return hr;
}
IFACEMETHODIMP MonacoPreviewHandler::DoPreview()
{
try
{
Logger::info(L"Starting MonacoPreviewHandler.exe");
STARTUPINFO info = { sizeof(info) };
std::wstring cmdLine{ L"\"" + m_filePath + L"\"" };
cmdLine += L" ";
std::wostringstream ss;
ss << std::hex << m_hwndParent;
cmdLine += ss.str();
cmdLine += L" ";
cmdLine += std::to_wstring(m_rcParent.left);
cmdLine += L" ";
cmdLine += std::to_wstring(m_rcParent.right);
cmdLine += L" ";
cmdLine += std::to_wstring(m_rcParent.top);
cmdLine += L" ";
cmdLine += std::to_wstring(m_rcParent.bottom);
std::wstring appPath = get_module_folderpath(g_hInst) + L"\\PowerToys.MonacoPreviewHandler.exe";
SHELLEXECUTEINFO sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = appPath.c_str();
sei.lpParameters = cmdLine.c_str();
sei.nShow = SW_SHOWDEFAULT;
ShellExecuteEx(&sei);
m_process = sei.hProcess;
}
catch (std::exception& e)
{
std::wstring errorMessage = std::wstring{ winrt::to_hstring(e.what()) };
Logger::error(L"Failed to start MonacoPreviewHandler.exe. Error: {}", errorMessage);
}
return S_OK;
}
IFACEMETHODIMP MonacoPreviewHandler::Unload()
{
Logger::info(L"Unload and terminate .exe");
m_hwndParent = NULL;
TerminateProcess(m_process, 0);
return S_OK;
}
#pragma endregion
#pragma region IPreviewHandlerVisuals
IFACEMETHODIMP MonacoPreviewHandler::SetBackgroundColor(COLORREF color)
{
return S_OK;
}
IFACEMETHODIMP MonacoPreviewHandler::SetFont(const LOGFONTW* plf)
{
return S_OK;
}
IFACEMETHODIMP MonacoPreviewHandler::SetTextColor(COLORREF color)
{
return S_OK;
}
#pragma endregion
#pragma region IOleWindow
IFACEMETHODIMP MonacoPreviewHandler::GetWindow(HWND* phwnd)
{
HRESULT hr = E_INVALIDARG;
if (phwnd)
{
*phwnd = m_hwndParent;
hr = S_OK;
}
return hr;
}
IFACEMETHODIMP MonacoPreviewHandler::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
}
#pragma endregion
#pragma region IObjectWithSite
IFACEMETHODIMP MonacoPreviewHandler::SetSite(IUnknown* punkSite)
{
if (m_punkSite)
{
m_punkSite->Release();
m_punkSite = NULL;
}
return punkSite ? punkSite->QueryInterface(&m_punkSite) : S_OK;
}
IFACEMETHODIMP MonacoPreviewHandler::GetSite(REFIID riid, void** ppv)
{
*ppv = NULL;
return m_punkSite ? m_punkSite->QueryInterface(riid, ppv) : E_FAIL;
}
#pragma endregion
#pragma region Helper Functions
#pragma endregion

View File

@ -0,0 +1,70 @@
#pragma once
#include "pch.h"
#include <filesystem>
#include <ShlObj.h>
#include <string>
class MonacoPreviewHandler :
public IInitializeWithFile,
public IPreviewHandler,
public IPreviewHandlerVisuals,
public IOleWindow,
public IObjectWithSite
{
public:
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv);
IFACEMETHODIMP_(ULONG) AddRef();
IFACEMETHODIMP_(ULONG) Release();
// IInitializeWithFile
IFACEMETHODIMP Initialize(LPCWSTR pszFilePath, DWORD grfMode);
// IPreviewHandler
IFACEMETHODIMP SetWindow(HWND hwnd, const RECT* prc);
IFACEMETHODIMP SetFocus();
IFACEMETHODIMP QueryFocus(HWND* phwnd);
IFACEMETHODIMP TranslateAccelerator(MSG* pmsg);
IFACEMETHODIMP SetRect(const RECT* prc);
IFACEMETHODIMP DoPreview();
IFACEMETHODIMP Unload();
// IPreviewHandlerVisuals
IFACEMETHODIMP SetBackgroundColor(COLORREF color);
IFACEMETHODIMP SetFont(const LOGFONTW* plf);
IFACEMETHODIMP SetTextColor(COLORREF color);
// IOleWindow
IFACEMETHODIMP GetWindow(HWND* phwnd);
IFACEMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
// IObjectWithSite
IFACEMETHODIMP SetSite(IUnknown* punkSite);
IFACEMETHODIMP GetSite(REFIID riid, void** ppv);
MonacoPreviewHandler();
protected:
~MonacoPreviewHandler();
private:
// Reference count of component.
long m_cRef;
// Provided during initialization.
std::wstring m_filePath;
// Parent window that hosts the previewer window.
// Note: do NOT DestroyWindow this.
HWND m_hwndParent;
// Bounding rect of the parent window.
RECT m_rcParent;
// Site pointer from host, used to get IPreviewHandlerFrame.
IUnknown* m_punkSite;
HANDLE m_process;
HANDLE m_resizeEvent;
};

View File

@ -0,0 +1,40 @@
#include <windows.h>
#include "resource.h"
#include "../../../common/version/version.h"
#define APSTUDIO_READONLY_SYMBOLS
#include "winres.h"
#undef APSTUDIO_READONLY_SYMBOLS
1 VERSIONINFO
FILEVERSION FILE_VERSION
PRODUCTVERSION PRODUCT_VERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
BEGIN
VALUE "CompanyName", COMPANY_NAME
VALUE "FileDescription", FILE_DESCRIPTION
VALUE "FileVersion", FILE_VERSION_STRING
VALUE "InternalName", INTERNAL_NAME
VALUE "LegalCopyright", COPYRIGHT_NOTE
VALUE "OriginalFilename", ORIGINAL_FILENAME
VALUE "ProductName", PRODUCT_NAME
VALUE "ProductVersion", PRODUCT_VERSION_STRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
END
END

View File

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{b3e869c4-8210-4ebd-a621-ff4c4afcbfa9}</ProjectGuid>
<RootNamespace>MonacoPreviewHandlerCpp</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</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">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\</OutDir>
</PropertyGroup>
<PropertyGroup>
<TargetName>PowerToys.$(ProjectName)</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;MARKDOWNPREVIEWHANDLERCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>../../..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>GlobalExportFunctions.def</ModuleDefinitionFile>
<AdditionalDependencies>Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;MARKDOWNPREVIEWHANDLERCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>../../..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>GlobalExportFunctions.def</ModuleDefinitionFile>
<AdditionalDependencies>Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="ClassFactory.h" />
<ClInclude Include="MonacoPreviewHandler.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ClassFactory.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="MonacoPreviewHandler.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="GlobalExportFunctions.def" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="MonacoPreviewHandlerCpp.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\common\SettingsAPI\SettingsAPI.vcxproj">
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="..\..\..\..\deps\spdlog.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
</Target>
</Project>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ClassFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MonacoPreviewHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Resource Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ClassFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MonacoPreviewHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="GlobalExportFunctions.def">
<Filter>Source Files</Filter>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="MonacoPreviewHandlerCpp.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,73 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include "ClassFactory.h"
HINSTANCE g_hInst = NULL;
long g_cDllRef = 0;
// {D8034CFA-F34B-41FE-AD45-62FCBB52A6DA}
static const GUID CLSID_MonacoPreviewHandler = { 0xd8034cfa, 0xf34b, 0x41fe, { 0xad, 0x45, 0x62, 0xfc, 0xbb, 0x52, 0xa6, 0xda } };
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hInst = hModule;
DisableThreadLibraryCalls(hModule);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//
// FUNCTION: DllGetClassObject
//
// PURPOSE: Create the class factory and query to the specific interface.
//
// PARAMETERS:
// * rclsid - The CLSID that will associate the correct data and code.
// * riid - A reference to the identifier of the interface that the caller
// is to use to communicate with the class object.
// * ppv - The address of a pointer variable that receives the interface
// pointer requested in riid. Upon successful return, *ppv contains the
// requested interface pointer. If an error occurs, the interface pointer
// is NULL.
//
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
{
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
if (IsEqualCLSID(CLSID_MonacoPreviewHandler, rclsid))
{
hr = E_OUTOFMEMORY;
ClassFactory* pClassFactory = new ClassFactory();
if (pClassFactory)
{
hr = pClassFactory->QueryInterface(riid, ppv);
pClassFactory->Release();
}
}
return hr;
}
//
// FUNCTION: DllCanUnloadNow
//
// PURPOSE: Check if we can unload the component from the memory.
//
// NOTE: The component can be unloaded from the memory when its reference
// count is zero (i.e. nobody is still using the component).
//
STDAPI DllCanUnloadNow(void)
{
return g_cDllRef > 0 ? S_FALSE : S_OK;
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.220929.3" targetFramework="native" />
</packages>

Some files were not shown because too many files have changed in this diff Show More