From e6379028927845289ad6c26db526dd2a6f17fd8e Mon Sep 17 00:00:00 2001 From: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com> Date: Thu, 30 Jun 2022 22:10:14 +0200 Subject: [PATCH] [PowerRename][ImageResizer] Tier1 Win11 Context menu (#19000) * Test win11 tier1 context menu * Try to test signing * Cleanup * Cleanup project file * Sign dll Add PowerToys preffix Add assets to installer * expect.txt * Switch to named pipes Unregister package on uninstall Remove unneeded files Cleanup * Bring back check if package registered but use per-user method * Fix win11 check * expect.txt * Check if package already registered * Revert "Check if package already registered" FindPackages() method needs admin privileges. This reverts commit 5af584fed4183d76d0a37dab4235e3f2557901c7. * Fix PowerRename args checking * Cleanup assets * Tier1 context menu ImageResizer Minor cleanups Move logic to package.h * [WIP] Signing and installer Expect.txt * Localized context menu title * Retarget everything 10.0.18362.0 -> 10.0.19041.0 * Address PR comments - check if selection renamable - minor cleanup - struct initialization * Fix ImageResizerLib project configuration * More Windows version updates * Remove unneeded file & try fix resource build error * Add Microsoft.PowerToys prefix to packages * Test * Fix convert-resx-to-rc.ps1 script issue causing resource files compile error Don't generate empty STRINGTABLE for resx files without data * Avoid duplicate context menu items * [BugReportTool] Report installed context menu packages --- .github/actions/spell-check/expect.txt | 32 +- .pipelines/ESRPSigning_core.json | 4 + Cpp.Build.props | 2 +- PowerToys.sln | 46 ++ .../modules/launcher/plugins/registry.md | 2 +- .../launcher/plugins/windowssettings.md | 2 +- installer/MSIX/build_msix_cdpx.cmd | 2 +- installer/PowerToysSetup/PowerToys.wxs | 2 +- .../PowerToysSetup/PowerToysInstaller.wixproj | 4 +- installer/PowerToysSetup/Product.wxs | 50 +- .../CustomAction.cpp | 78 +- .../CustomAction.def | 2 +- .../PowerToysSetupCustomActions.vcxproj | 20 +- .../packages.config | 1 + src/common/logger/logger_settings.h | 1 + src/common/utils/package.h | 112 +++ src/logging/logging.vcxproj | 2 +- .../FindMyMouse/FindMyMouse.vcxproj | 2 +- .../MouseHighlighter/MouseHighlighter.vcxproj | 2 +- .../MousePointerCrosshairs.vcxproj | 2 +- .../ShortcutGuide/ShortcutGuide.vcxproj | 2 +- .../ShortcutGuideModuleInterface.vcxproj | 2 +- .../AlwaysOnTop/AlwaysOnTop.vcxproj | 2 +- src/modules/awake/Awake/Awake.csproj | 4 +- .../AwakeModuleInterface.vcxproj | 2 +- .../ColorPickerUI/ColorPickerUI.csproj | 2 +- .../UnitTest-ColorPickerUI.csproj | 2 +- .../fancyzones/FancyZones/FancyZones.vcxproj | 2 +- .../UnitTests/UnitTests.vcxproj | 2 +- .../FancyZonesEditor/FancyZonesEditor.csproj | 2 +- .../ImageResizerContextMenu/AppxManifest.xml | 55 ++ .../Assets/LargeTile.png | Bin 0 -> 1755 bytes .../Assets/SmallTile.png | Bin 0 -> 637 bytes .../Assets/SplashScreen.png | Bin 0 -> 7700 bytes .../Assets/Square150x150Logo.png | Bin 0 -> 1755 bytes .../Assets/Square44x44Logo.png | Bin 0 -> 637 bytes .../Assets/Wide310x150Logo.png | Bin 0 -> 2097 bytes .../Assets/storelogo.png | Bin 0 -> 456 bytes .../ImageResizerContextMenu/ImageResizer.ico | Bin 0 -> 122959 bytes .../ImageResizerContextMenu.base.rc | 50 ++ .../ImageResizerContextMenu.vcxproj | 135 ++++ .../ImageResizerContextMenu.vcxproj.filters | 59 ++ .../ImageResizerContextMenu/Resources.resx | 126 +++ .../ImageResizerContextMenu/Source.def | 5 + .../ImageResizerContextMenu/dllmain.cpp | 272 +++++++ .../ImageResizerContextMenu/framework.h | 5 + .../ImageResizerContextMenu/packages.config | 5 + .../ImageResizerContextMenu/pch.cpp | 5 + .../ImageResizerContextMenu/pch.h | 13 + .../ImageResizerContextMenu/resource.base.h | 13 + .../ImageResizerContextMenu/targetver.h | 4 + .../ImageResizerConstants.h | 0 .../ImageResizerLib/ImageResizerLib.vcxproj | 83 ++ .../ImageResizerLib.vcxproj.filters | 45 ++ .../{dll => ImageResizerLib}/Settings.cpp | 248 +++--- .../{dll => ImageResizerLib}/Settings.h | 74 +- .../imageresizer/ImageResizerLib/framework.h | 6 + .../imageresizer/ImageResizerLib/pch.cpp | 5 + .../imageresizer/ImageResizerLib/pch.h | 18 + .../{dll => ImageResizerLib}/trace.cpp | 118 +-- .../{dll => ImageResizerLib}/trace.h | 22 +- .../imageresizer/dll/ContextMenuHandler.cpp | 11 +- .../imageresizer/dll/ImageResizerExt.vcxproj | 14 +- .../dll/ImageResizerExt.vcxproj.filters | 15 - src/modules/imageresizer/dll/dllmain.cpp | 29 +- .../tests/ImageResizerUITest.csproj | 2 +- .../imageresizer/ui/ImageResizerUI.csproj | 2 +- .../imageresizer/ui/Models/ResizeBatch.cs | 52 +- .../KeyboardManagerEditor.exe.manifest | 2 +- .../KeyboardManagerEditor.vcxproj | 4 +- .../KeyboardManagerEditorLibrary.vcxproj | 4 +- .../KeyboardManagerEditorTest.vcxproj | 2 +- .../KeyboardManagerEngine.vcxproj | 4 +- .../KeyboardManagerEngineLibrary.vcxproj | 4 +- .../KeyboardManagerEngineTest.vcxproj | 2 +- .../common/KeyboardManagerCommon.vcxproj | 2 +- .../dll/KeyboardManager.vcxproj | 2 +- .../Microsoft.Launcher.vcxproj | 2 +- .../DevelopmentApp/AppxManifest.xml | 2 +- .../FrameworkApp/AppxManifest.xml | 2 +- .../PackagedApp/AppxManifest.xml | 2 +- .../Microsoft.Plugin.Program.UnitTests.csproj | 2 +- .../Microsoft.Plugin.Program.csproj | 2 +- ...ft.Plugin.WindowsTerminal.UnitTests.csproj | 2 +- ...owerToys.Run.Plugin.WindowsTerminal.csproj | 2 +- .../PowerLauncher/PowerLauncher.csproj | 2 +- .../InstallationPublishProfile.pubxml | 2 +- src/modules/launcher/Wox.Test/Wox.Test.csproj | 2 +- .../PowerRenameContextMenu/AppxManifest.xml | 61 ++ .../Assets/LargeTile.png | Bin 0 -> 1755 bytes .../Assets/SmallTile.png | Bin 0 -> 637 bytes .../Assets/SplashScreen.png | Bin 0 -> 7700 bytes .../Assets/Square150x150Logo.png | Bin 0 -> 1755 bytes .../Assets/Square44x44Logo.png | Bin 0 -> 637 bytes .../Assets/Wide310x150Logo.png | Bin 0 -> 2097 bytes .../Assets/storelogo.png | Bin 0 -> 456 bytes .../PowerRenameContextMenu.rc | 60 ++ .../PowerRenameContextMenu.vcxproj | 128 +++ .../PowerRenameContextMenu.vcxproj.filters | 742 ++++++++++++++++++ .../PowerRenameContextMenu/PowerRenameUI.ico | Bin 0 -> 118203 bytes .../PowerRenameContextMenu/Source.def | 5 + .../PowerRenameContextMenu/dllmain.cpp | 277 +++++++ .../PowerRenameContextMenu/framework.h | 5 + .../PowerRenameContextMenu/packages.config | 5 + .../PowerRenameContextMenu/pch.cpp | 5 + .../powerrename/PowerRenameContextMenu/pch.h | 13 + .../PowerRenameContextMenu/resource.h | 14 + .../powerrename/PowerRenameUILib/App.xaml.cpp | 50 +- .../PowerRenameUILib/PowerRenameUI.vcxproj | 2 +- .../powerrename/dll/PowerRenameExt.cpp | 26 +- .../powerrename/dll/PowerRenameExt.vcxproj | 5 +- src/modules/powerrename/dll/dllmain.cpp | 26 +- src/modules/powerrename/lib/Helpers.cpp | 25 + src/modules/powerrename/lib/Helpers.h | 1 + .../GcodePreviewHandler.csproj | 2 +- .../MarkdownPreviewHandler.csproj | 2 +- .../InstallationPublishProfile.pubxml | 2 +- .../MonacoPreviewHandler.csproj | 2 +- .../InstallationPublishProfile.pubxml | 2 +- .../PdfPreviewHandler.csproj | 2 +- .../PdfThumbnailProvider.csproj | 2 +- .../InstallationPublishProfile.pubxml | 2 +- .../SvgPreviewHandler.csproj | 2 +- .../InstallationPublishProfile.pubxml | 2 +- .../SvgThumbnailProvider.csproj | 2 +- .../UnitTests-GcodePreviewHandler.csproj | 2 +- .../UnitTests-GcodeThumbnailProvider.csproj | 2 +- .../UnitTests-MarkdownPreviewHandler.csproj | 2 +- .../UnitTests-PdfPreviewHandler.csproj | 2 +- .../UnitTests-PdfThumbnailProvider.csproj | 2 +- .../UnitTests-StlThumbnailProvider.csproj | 2 +- .../UnitTests-SvgPreviewHandler.csproj | 2 +- .../UnitTests-SvgThumbnailProvider.csproj | 2 +- .../VideoConference.vcxproj | 2 +- .../VideoConferenceProxyFilter.vcxproj | 2 +- .../VideoConferenceShared.vcxproj | 2 +- src/runner/PowerToys.exe.manifest | 2 +- .../Settings.UI/PowerToys.Settings.csproj | 2 +- .../InstallationPublishProfile.pubxml | 2 +- .../BugReportTool/BugReportTool.vcxproj | 2 + .../BugReportTool.vcxproj.filters | 2 + tools/BugReportTool/BugReportTool/Main.cpp | 3 + tools/BugReportTool/BugReportTool/Package.cpp | 78 ++ tools/BugReportTool/BugReportTool/Package.h | 13 + .../MonitorReportTool.vcxproj | 2 +- .../StylesReportTool/StylesReportTool.vcxproj | 2 +- tools/build/convert-resx-to-rc.ps1 | 14 +- .../ModuleTemplateCompileTest.vcxproj | 2 +- 148 files changed, 3163 insertions(+), 384 deletions(-) create mode 100644 src/common/utils/package.h create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/AppxManifest.xml create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/Assets/LargeTile.png create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/Assets/SmallTile.png create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/Assets/SplashScreen.png create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/Assets/Square150x150Logo.png create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/Assets/Square44x44Logo.png create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/Assets/Wide310x150Logo.png create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/Assets/storelogo.png create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/ImageResizer.ico create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.base.rc create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj.filters create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/Resources.resx create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/Source.def create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/dllmain.cpp create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/framework.h create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/packages.config create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/pch.cpp create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/pch.h create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/resource.base.h create mode 100644 src/modules/imageresizer/ImageResizerContextMenu/targetver.h rename src/modules/imageresizer/{dll => ImageResizerLib}/ImageResizerConstants.h (100%) create mode 100644 src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj create mode 100644 src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj.filters rename src/modules/imageresizer/{dll => ImageResizerLib}/Settings.cpp (94%) rename src/modules/imageresizer/{dll => ImageResizerLib}/Settings.h (93%) create mode 100644 src/modules/imageresizer/ImageResizerLib/framework.h create mode 100644 src/modules/imageresizer/ImageResizerLib/pch.cpp create mode 100644 src/modules/imageresizer/ImageResizerLib/pch.h rename src/modules/imageresizer/{dll => ImageResizerLib}/trace.cpp (96%) rename src/modules/imageresizer/{dll => ImageResizerLib}/trace.h (96%) create mode 100644 src/modules/powerrename/PowerRenameContextMenu/AppxManifest.xml create mode 100644 src/modules/powerrename/PowerRenameContextMenu/Assets/LargeTile.png create mode 100644 src/modules/powerrename/PowerRenameContextMenu/Assets/SmallTile.png create mode 100644 src/modules/powerrename/PowerRenameContextMenu/Assets/SplashScreen.png create mode 100644 src/modules/powerrename/PowerRenameContextMenu/Assets/Square150x150Logo.png create mode 100644 src/modules/powerrename/PowerRenameContextMenu/Assets/Square44x44Logo.png create mode 100644 src/modules/powerrename/PowerRenameContextMenu/Assets/Wide310x150Logo.png create mode 100644 src/modules/powerrename/PowerRenameContextMenu/Assets/storelogo.png create mode 100644 src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.rc create mode 100644 src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj create mode 100644 src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj.filters create mode 100644 src/modules/powerrename/PowerRenameContextMenu/PowerRenameUI.ico create mode 100644 src/modules/powerrename/PowerRenameContextMenu/Source.def create mode 100644 src/modules/powerrename/PowerRenameContextMenu/dllmain.cpp create mode 100644 src/modules/powerrename/PowerRenameContextMenu/framework.h create mode 100644 src/modules/powerrename/PowerRenameContextMenu/packages.config create mode 100644 src/modules/powerrename/PowerRenameContextMenu/pch.cpp create mode 100644 src/modules/powerrename/PowerRenameContextMenu/pch.h create mode 100644 src/modules/powerrename/PowerRenameContextMenu/resource.h create mode 100644 tools/BugReportTool/BugReportTool/Package.cpp create mode 100644 tools/BugReportTool/BugReportTool/Package.h diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index a624ef3d49..130f458b55 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -192,6 +192,7 @@ buf BUFSIZE bugreport BUILDARCH +BUILDNUMBER buildtask buildtransitive Burkina @@ -466,6 +467,7 @@ dlib DLIMAGES dllexport dllhost +dllimport dllmain dlls DNLEN @@ -497,6 +499,7 @@ DVSD DVSL DVTARGETDEVICE DWINRT +dwl dwm dwmapi dwmcorei @@ -511,6 +514,7 @@ DWMWCP DWMWINDOWATTRIBUTE DWMWINDOWMAXIMIZEDCHANGE dword +DWORDLONG dworigin dwrite dxgi @@ -548,9 +552,9 @@ Eqn ERASEBKGND EREOF EResize +ERole ERRORMESSAGE ERRORTITLE -ERole ESettings esize esrp @@ -722,6 +726,7 @@ HHOOK hhx Hiber Hiberboot +HIBYTE HICON HIDEWINDOW highlighter @@ -785,6 +790,7 @@ HWNDNEXT HWNDPREV IAction IActivated +IActivation IAnimatable IApp IApplication @@ -859,13 +865,15 @@ IInspectable IIO IItem IJson -IKs Ijwhost +IKs IList ILogon IMAGEHLP imageresizer +IMAGERESIZERCONTEXTMENU IMAGERESIZEREXT +imageresizerinput imageresizersettings imagingdevices IMain @@ -1092,6 +1100,7 @@ LIBID Lifecycle LIGHTORANGE LIGHTTURQUOISE +lightunplated lindex linkedin linq @@ -1107,6 +1116,7 @@ LMEM LMENU lnk LOADSTRING +LOBYTE LOCALAPPDATA LOCALDISPLAY LOCALPACKAGE @@ -1168,6 +1178,7 @@ Macquarie Magadan Mainwindow majortype +MAJORVERSION makeappx makecab MAKEINTRESOURCE @@ -1239,6 +1250,7 @@ MINIMIZEEND MINIMIZESTART miniz minlevel +MINORVERSION Miracast mirophone Mishkeegogamang @@ -1423,6 +1435,7 @@ NTFS NTSTATUS nuget nuint +nullonfailure nullopt nullptr numberbox @@ -1468,7 +1481,9 @@ oss ostr ostream ostringstream +OSVERSIONINFOEX OSVERSIONINFOEXW +osvi otating OUTOFCONTEXT OUTOFMEMORY @@ -1556,6 +1571,8 @@ powercfg powerlauncher powerpreview powerrename +POWERRENAMECONTEXTMENU +powerrenameinput POWERRENAMETEST powertoy powertoysinterop @@ -1770,6 +1787,7 @@ RUNLEVEL runsettings runtimeclass runtimeconfig +runtimeobject runtimes RUS rvalue @@ -1965,6 +1983,7 @@ stl stoi stol stoll +storelogo stoul stoull strcmp @@ -2167,6 +2186,7 @@ unregister unregistering unremapped unsubscribe +unvirtualized Updatelayout UPGRADINGPRODUCTCODE upto @@ -2215,8 +2235,8 @@ VERIFYCONTEXT verrsrc VERSIONINFO Versioning -VFT vformat +VFT vid VIDCAP videoconference @@ -2267,8 +2287,8 @@ wdp wdupenv weakme webcam -webserver webpage +webserver website webview wekyb @@ -2298,8 +2318,8 @@ WINDOWPLACEMENT WINDOWPOSCHANGED WINDOWPOSCHANGING Windowsapp -windowsappsdk windowsappruntimeinstall +windowsappsdk WINDOWSBUILDNUMBER Windowscodecs windowsdesktop @@ -2326,6 +2346,7 @@ winrt winsdk winsdkver winspool +WINTHRESHOLD winui winxamlmanager wistd @@ -2369,6 +2390,7 @@ wregex WResize writefile Wrk +wrl wsf wsh wsl diff --git a/.pipelines/ESRPSigning_core.json b/.pipelines/ESRPSigning_core.json index 9c1625f529..e4058d8254 100644 --- a/.pipelines/ESRPSigning_core.json +++ b/.pipelines/ESRPSigning_core.json @@ -68,6 +68,8 @@ "modules\\ImageResizer\\PowerToys.ImageResizer.exe", "modules\\ImageResizer\\PowerToys.ImageResizer.dll", "modules\\ImageResizer\\PowerToys.ImageResizerExt.dll", + "modules\\ImageResizer\\PowerToys.ImageResizerContextMenu.dll", + "modules\\ImageResizer\\ImageResizerContextMenuPackage.msix", "modules\\KeyboardManager\\PowerToys.KeyboardManager.dll", "modules\\KeyboardManager\\KeyboardManagerEditor\\PowerToys.KeyboardManagerEditor.exe", @@ -105,6 +107,8 @@ "modules\\PowerRename\\PowerToys.PowerRenameExt.dll", "modules\\PowerRename\\PowerToys.PowerRename.exe", + "modules\\PowerRename\\PowerToys.PowerRenameContextMenu.dll", + "modules\\PowerRename\\PowerRenameContextMenuPackage.msix", "modules\\ShortcutGuide\\ShortcutGuide\\PowerToys.ShortcutGuide.exe", "modules\\ShortcutGuide\\ShortcutGuideModuleInterface\\PowerToys.ShortcutGuideModuleInterface.dll", diff --git a/Cpp.Build.props b/Cpp.Build.props index 059ae21213..b58ed24173 100644 --- a/Cpp.Build.props +++ b/Cpp.Build.props @@ -84,7 +84,7 @@ - 10.0.18362.0 + 10.0.19041.0 diff --git a/PowerToys.sln b/PowerToys.sln index 1bdda455f5..078ab61953 100644 --- a/PowerToys.sln +++ b/PowerToys.sln @@ -279,6 +279,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "utils", "utils", "{B39DC643 src\common\utils\modulesRegistry.h = src\common\utils\modulesRegistry.h src\common\utils\MsiUtils.h = src\common\utils\MsiUtils.h src\common\utils\os-detect.h = src\common\utils\os-detect.h + src\common\utils\package.h = src\common\utils\package.h src\common\utils\ProcessWaiter.h = src\common\utils\ProcessWaiter.h src\common\utils\process_path.h = src\common\utils\process_path.h src\common\utils\registry.h = src\common\utils\registry.h @@ -404,10 +405,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerToys.Settings", "src\s EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameUI", "src\modules\powerrename\PowerRenameUILib\PowerRenameUI.vcxproj", "{27718999-C175-450A-861C-89F911E16A88}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRenameContextMenu", "src\modules\powerrename\PowerRenameContextMenu\PowerRenameContextMenu.vcxproj", "{1DBBB112-4BB1-444B-8EBB-E66555C76BA6}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerToys.Run.Plugin.TimeZone.UnitTests", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.TimeZone.UnitTests\Microsoft.PowerToys.Run.Plugin.TimeZone.UnitTests.csproj", "{C5D46169-5334-48C3-8C28-644C72832E54}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerToys.Run.Plugin.OneNote", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.OneNote\Microsoft.PowerToys.Run.Plugin.OneNote.csproj", "{5A1DB2F0-0715-4B3B-98E6-79BC41540045}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageResizerContextMenu", "src\modules\imageresizer\ImageResizerContextMenu\ImageResizerContextMenu.vcxproj", "{93B72A06-C8BD-484F-A6F7-C9F280B150BF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImageResizerLib", "src\modules\imageresizer\ImageResizerLib\ImageResizerLib.vcxproj", "{18B3DB45-4FFE-4D01-97D6-5223FEEE1853}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM64 = Debug|ARM64 @@ -1565,6 +1572,18 @@ Global {27718999-C175-450A-861C-89F911E16A88}.Release|x64.Build.0 = Release|x64 {27718999-C175-450A-861C-89F911E16A88}.Release|x86.ActiveCfg = Release|x64 {27718999-C175-450A-861C-89F911E16A88}.Release|x86.Build.0 = Release|x64 + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6}.Debug|ARM64.Build.0 = Debug|ARM64 + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6}.Debug|x64.ActiveCfg = Debug|x64 + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6}.Debug|x64.Build.0 = Debug|x64 + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6}.Debug|x86.ActiveCfg = Debug|x64 + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6}.Debug|x86.Build.0 = Debug|x64 + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6}.Release|ARM64.ActiveCfg = Release|ARM64 + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6}.Release|ARM64.Build.0 = Release|ARM64 + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6}.Release|x64.ActiveCfg = Release|x64 + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6}.Release|x64.Build.0 = Release|x64 + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6}.Release|x86.ActiveCfg = Release|x64 + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6}.Release|x86.Build.0 = Release|x64 {C5D46169-5334-48C3-8C28-644C72832E54}.Debug|ARM64.ActiveCfg = Debug|ARM64 {C5D46169-5334-48C3-8C28-644C72832E54}.Debug|ARM64.Build.0 = Debug|ARM64 {C5D46169-5334-48C3-8C28-644C72832E54}.Debug|x64.ActiveCfg = Debug|x64 @@ -1589,6 +1608,30 @@ Global {5A1DB2F0-0715-4B3B-98E6-79BC41540045}.Release|x64.Build.0 = Release|x64 {5A1DB2F0-0715-4B3B-98E6-79BC41540045}.Release|x86.ActiveCfg = Release|x64 {5A1DB2F0-0715-4B3B-98E6-79BC41540045}.Release|x86.Build.0 = Release|x64 + {93B72A06-C8BD-484F-A6F7-C9F280B150BF}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {93B72A06-C8BD-484F-A6F7-C9F280B150BF}.Debug|ARM64.Build.0 = Debug|ARM64 + {93B72A06-C8BD-484F-A6F7-C9F280B150BF}.Debug|x64.ActiveCfg = Debug|x64 + {93B72A06-C8BD-484F-A6F7-C9F280B150BF}.Debug|x64.Build.0 = Debug|x64 + {93B72A06-C8BD-484F-A6F7-C9F280B150BF}.Debug|x86.ActiveCfg = Debug|x64 + {93B72A06-C8BD-484F-A6F7-C9F280B150BF}.Debug|x86.Build.0 = Debug|x64 + {93B72A06-C8BD-484F-A6F7-C9F280B150BF}.Release|ARM64.ActiveCfg = Release|ARM64 + {93B72A06-C8BD-484F-A6F7-C9F280B150BF}.Release|ARM64.Build.0 = Release|ARM64 + {93B72A06-C8BD-484F-A6F7-C9F280B150BF}.Release|x64.ActiveCfg = Release|x64 + {93B72A06-C8BD-484F-A6F7-C9F280B150BF}.Release|x64.Build.0 = Release|x64 + {93B72A06-C8BD-484F-A6F7-C9F280B150BF}.Release|x86.ActiveCfg = Release|x64 + {93B72A06-C8BD-484F-A6F7-C9F280B150BF}.Release|x86.Build.0 = Release|x64 + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Debug|ARM64.Build.0 = Debug|ARM64 + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Debug|x64.ActiveCfg = Debug|x64 + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Debug|x64.Build.0 = Debug|x64 + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Debug|x86.ActiveCfg = Debug|x64 + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Debug|x86.Build.0 = Debug|x64 + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Release|ARM64.ActiveCfg = Release|ARM64 + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Release|ARM64.Build.0 = Release|ARM64 + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Release|x64.ActiveCfg = Release|x64 + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Release|x64.Build.0 = Release|x64 + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Release|x86.ActiveCfg = Release|x64 + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853}.Release|x86.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1722,8 +1765,11 @@ Global {8FE5A5EE-1B59-401C-9FB3-B04ECD3E29C1} = {4AFC9975-2456-4C70-94A4-84073C1CED93} {020A7474-3601-4160-A159-D7B70B77B15F} = {C3081D9A-1586-441A-B5F4-ED815B3719C1} {27718999-C175-450A-861C-89F911E16A88} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3} + {1DBBB112-4BB1-444B-8EBB-E66555C76BA6} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3} {C5D46169-5334-48C3-8C28-644C72832E54} = {4AFC9975-2456-4C70-94A4-84073C1CED93} {5A1DB2F0-0715-4B3B-98E6-79BC41540045} = {4AFC9975-2456-4C70-94A4-84073C1CED93} + {93B72A06-C8BD-484F-A6F7-C9F280B150BF} = {6C7F47CC-2151-44A3-A546-41C70025132C} + {18B3DB45-4FFE-4D01-97D6-5223FEEE1853} = {6C7F47CC-2151-44A3-A546-41C70025132C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0} diff --git a/doc/devdocs/modules/launcher/plugins/registry.md b/doc/devdocs/modules/launcher/plugins/registry.md index fba1b4f233..299b77e5af 100644 --- a/doc/devdocs/modules/launcher/plugins/registry.md +++ b/doc/devdocs/modules/launcher/plugins/registry.md @@ -78,7 +78,7 @@ The plugin use only these interfaces (all inside the `Main.cs`): | Name | Value | | --------------- | ------------------------------------------------------------------------------ | -| TargetFramework | `net6.0-windows` (.NET 5) or `net6.0-windows10.0.18362.0` (OS version specific)| +| TargetFramework | `net6.0-windows` (.NET 5) or `net6.0-windows10.0.19041.0` (OS version specific)| | LangVersion | `8.0` (mean C# 8.0) | | Platforms | `x64` | | Nullable | `true` | diff --git a/doc/devdocs/modules/launcher/plugins/windowssettings.md b/doc/devdocs/modules/launcher/plugins/windowssettings.md index 6f3701f6b8..a6eafb396c 100644 --- a/doc/devdocs/modules/launcher/plugins/windowssettings.md +++ b/doc/devdocs/modules/launcher/plugins/windowssettings.md @@ -141,7 +141,7 @@ Because the JSON file must have a object as root type, instead of a array. | Name | Value | | --------------- | --------------------------------------------------------------------------------------------------- | -| TargetFramework | `net6.0-windows` (.NET 5) or `net6.0-windows10.0.18362.0` (OS version specific) | +| TargetFramework | `net6.0-windows` (.NET 5) or `net6.0-windows10.0.19041.0` (OS version specific) | | Platforms | `x64` | | Output | `..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsSettings\` | | RootNamespace | `Microsoft.PowerToys.Run.Plugin.WindowsSettings` | diff --git a/installer/MSIX/build_msix_cdpx.cmd b/installer/MSIX/build_msix_cdpx.cmd index 261a6a6818..d47353ae7f 100644 --- a/installer/MSIX/build_msix_cdpx.cmd +++ b/installer/MSIX/build_msix_cdpx.cmd @@ -1,6 +1,6 @@ cd /D "%~dp0" -call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0 +call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.19041.0 powershell -file update_appxmanifest_version.ps1 || exit /b 1 diff --git a/installer/PowerToysSetup/PowerToys.wxs b/installer/PowerToysSetup/PowerToys.wxs index f585c2a381..b53bfd9909 100644 --- a/installer/PowerToysSetup/PowerToys.wxs +++ b/installer/PowerToysSetup/PowerToys.wxs @@ -67,7 +67,7 @@ - DetectedWindowsBuildNumber >= 18362 OR WixBundleInstalled + DetectedWindowsBuildNumber >= 19041 OR WixBundleInstalled diff --git a/installer/PowerToysSetup/PowerToysInstaller.wixproj b/installer/PowerToysSetup/PowerToysInstaller.wixproj index 99419ce6d7..1e387d8d02 100644 --- a/installer/PowerToysSetup/PowerToysInstaller.wixproj +++ b/installer/PowerToysSetup/PowerToysInstaller.wixproj @@ -10,7 +10,7 @@ using a specific profile. If you're doing local installer builds, this will simulate the build pipeline doing that for you. --> IF NOT DEFINED IsPipeline ( -call "$([MSBuild]::GetVsInstallRoot())\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.18362.0 +call "$([MSBuild]::GetVsInstallRoot())\Common7\Tools\VsDevCmd.bat" -arch=amd64 -host_arch=amd64 -winsdk=10.0.19041.0 SET PTRoot=..\..\..\.. call "..\..\publish.cmd" x64 ) @@ -19,7 +19,7 @@ call "..\..\publish.cmd" x64 Version=$(Version);MonacoSRCHarvestPath=$(ProjectDir)..\..\ARM64\$(Configuration)\modules\FileExplorerPreview\monacoSRC IF NOT DEFINED IsPipeline ( -call "$([MSBuild]::GetVsInstallRoot())\Common7\Tools\VsDevCmd.bat" -arch=arm64 -host_arch=amd64 -winsdk=10.0.18362.0 +call "$([MSBuild]::GetVsInstallRoot())\Common7\Tools\VsDevCmd.bat" -arch=arm64 -host_arch=amd64 -winsdk=10.0.19041.0 SET PTRoot=..\..\..\.. call "..\..\publish.cmd" arm64 ) diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs index abf7d2ca2a..0a863871fe 100644 --- a/installer/PowerToysSetup/Product.wxs +++ b/installer/PowerToysSetup/Product.wxs @@ -42,11 +42,11 @@ - + - + @@ -108,7 +108,11 @@ - + + + + + @@ -136,8 +140,8 @@ - - = 18362)]]> + + = 19041)]]> @@ -226,6 +230,9 @@ Installed AND (REMOVE="ALL") + + Installed AND (REMOVE="ALL") + @@ -391,7 +406,9 @@ - + + + @@ -720,6 +737,15 @@ + + + + + + + + + @@ -755,6 +781,12 @@ + + + + + + @@ -779,7 +811,7 @@ - WINDOWSBUILDNUMBER >= 18362 + WINDOWSBUILDNUMBER >= 19041 @@ -793,7 +825,7 @@ - WINDOWSBUILDNUMBER >= 18362 + WINDOWSBUILDNUMBER >= 19041 @@ -1011,9 +1043,11 @@ + + diff --git a/installer/PowerToysSetupCustomActions/CustomAction.cpp b/installer/PowerToysSetupCustomActions/CustomAction.cpp index 8a942d3348..b8fa58967f 100644 --- a/installer/PowerToysSetupCustomActions/CustomAction.cpp +++ b/installer/PowerToysSetupCustomActions/CustomAction.cpp @@ -11,6 +11,10 @@ #include "../../src/common/updating/installer.h" #include "../../src/common/version/version.h" +#include +#include +#include + using namespace std; HINSTANCE DLL_HANDLE = nullptr; @@ -912,7 +916,7 @@ LExit: if (!SUCCEEDED(hr)) { PMSIHANDLE hRecord = MsiCreateRecord(0); - MsiRecordSetString(hRecord, 0, TEXT("Filed to iminstall virtual camera driver")); + MsiRecordSetString(hRecord, 0, TEXT("Failed to uninstall virtual camera driver")); MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING + MB_OK), hRecord); } @@ -920,6 +924,78 @@ LExit: return WcaFinalize(er); } +UINT __stdcall UnRegisterContextMenuPackagesCA(MSIHANDLE hInstall) +{ + using namespace winrt::Windows::Foundation; + using namespace winrt::Windows::Management::Deployment; + + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + hr = WcaInitialize(hInstall, "UnRegisterContextMenuPackagesCA"); // original func name is too long + + try + { + // Packages to unregister + const std::vector packagesToRemoveDisplayName{ { L"PowerRenameContextMenu" }, { L"ImageResizerContextMenu" } }; + + PackageManager packageManager; + + for (auto const& package : packageManager.FindPackages()) + { + const auto& packageFullName = std::wstring{ package.Id().FullName() }; + + for (const auto& packageToRemove : packagesToRemoveDisplayName) + { + if (packageFullName.contains(packageToRemove)) + { + auto deploymentOperation{ packageManager.RemovePackageAsync(packageFullName) }; + deploymentOperation.get(); + + // Check the status of the operation + if (deploymentOperation.Status() == AsyncStatus::Error) + { + auto deploymentResult{ deploymentOperation.GetResults() }; + auto errorCode = deploymentOperation.ErrorCode(); + auto errorText = deploymentResult.ErrorText(); + + Logger::error(L"Unregister {} package failed. ErrorCode: {}, ErrorText: {}", packageFullName, std::to_wstring(errorCode), errorText); + + er = ERROR_INSTALL_FAILURE; + } + else if (deploymentOperation.Status() == AsyncStatus::Canceled) + { + Logger::error(L"Unregister {} package canceled.", packageFullName); + + er = ERROR_INSTALL_FAILURE; + } + else if (deploymentOperation.Status() == AsyncStatus::Completed) + { + Logger::info(L"Unregister {} package completed.", packageFullName); + } + else + { + Logger::debug(L"Unregister {} package started.", packageFullName); + } + } + + } + } + } + catch (std::exception e) + { + std::string errorMessage{ "Exception thrown while trying to unregister sparse packages: " }; + errorMessage += e.what(); + Logger::error(errorMessage); + + er = ERROR_INSTALL_FAILURE; + } + + er = er == ERROR_SUCCESS ? (SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE) : er; + return WcaFinalize(er); +} + + UINT __stdcall TerminateProcessesCA(MSIHANDLE hInstall) { HRESULT hr = S_OK; diff --git a/installer/PowerToysSetupCustomActions/CustomAction.def b/installer/PowerToysSetupCustomActions/CustomAction.def index f8e4d84481..255b64724e 100644 --- a/installer/PowerToysSetupCustomActions/CustomAction.def +++ b/installer/PowerToysSetupCustomActions/CustomAction.def @@ -14,10 +14,10 @@ EXPORTS TelemetryLogRepairCancelCA TelemetryLogRepairFailCA TerminateProcessesCA - TerminateProcessesCA CertifyVirtualCameraDriverCA InstallVirtualCameraDriverCA InstallEmbeddedMSIXCA UnApplyModulesRegistryChangeSetsCA UninstallVirtualCameraDriverCA + UnRegisterContextMenuPackagesCA UninstallEmbeddedMSIXCA \ No newline at end of file diff --git a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj index f43503577e..277d690bb2 100644 --- a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj +++ b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj @@ -1,12 +1,12 @@ - + + {32f3882b-f2d6-4586-b5ed-11e39e522bd3} Win32Proj PowerToysSetupCustomActions - 10.0.18362.0 + 10.0.19041.0 PowerToysSetupCustomActions @@ -43,7 +43,6 @@ false ..\..\src\common\Telemetry;$(IncludePath) - inc;..\..\src\;..\..\src\common\Telemetry;telemetry;$(WixSdkPath)VS2017\inc;%(AdditionalIncludeDirectories) @@ -56,7 +55,6 @@ CustomAction.def - WIN64;%(PreprocessorDefinitions) @@ -65,7 +63,6 @@ $(WixSdkPath)VS2017\lib\$(Platform);%(AdditionalLibraryDirectories) - Disabled @@ -127,5 +124,14 @@ - + + + + + + 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}. + + + + \ No newline at end of file diff --git a/installer/PowerToysSetupCustomActions/packages.config b/installer/PowerToysSetupCustomActions/packages.config index 6b8deb9c96..fa024c0634 100644 --- a/installer/PowerToysSetupCustomActions/packages.config +++ b/installer/PowerToysSetupCustomActions/packages.config @@ -1,3 +1,4 @@  + \ No newline at end of file diff --git a/src/common/logger/logger_settings.h b/src/common/logger/logger_settings.h index 87e05ccf2e..5530a2ab8b 100644 --- a/src/common/logger/logger_settings.h +++ b/src/common/logger/logger_settings.h @@ -28,6 +28,7 @@ struct LogSettings inline const static std::string findMyMouseLoggerName = "find-my-mouse"; inline const static std::string mouseHighlighterLoggerName = "mouse-highlighter"; inline const static std::string mousePointerCrosshairsLoggerName = "mouse-pointer-crosshairs"; + inline const static std::string imageResizerLoggerName = "imageresizer"; inline const static std::string powerRenameLoggerName = "powerrename"; inline const static std::string alwaysOnTopLoggerName = "always-on-top"; inline const static std::wstring alwaysOnTopLogPath = L"always-on-top-log.txt"; diff --git a/src/common/utils/package.h b/src/common/utils/package.h new file mode 100644 index 0000000000..21fdaa3f84 --- /dev/null +++ b/src/common/utils/package.h @@ -0,0 +1,112 @@ +#pragma once + +#include + +#include +#include + +#include +#include +#include + +#include "../logger/logger.h" + +namespace package { + inline BOOL IsWin11OrGreater() + { + OSVERSIONINFOEX osvi{}; + DWORDLONG dwlConditionMask = 0; + int op = VER_GREATER_EQUAL; + + // Initialize the OSVERSIONINFOEX structure. + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + osvi.dwMajorVersion = HIBYTE(_WIN32_WINNT_WINTHRESHOLD); + osvi.dwMinorVersion = LOBYTE(_WIN32_WINNT_WINTHRESHOLD); + // Windows 11 build number + osvi.dwBuildNumber = 22000; + + // Initialize the condition mask. + VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op); + VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op); + VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, op); + + // Perform the test. + return VerifyVersionInfo( + &osvi, + VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER, + dwlConditionMask); + } + + inline bool IsPackageRegistered(std::wstring packageDisplayName) + { + using namespace winrt::Windows::Foundation; + using namespace winrt::Windows::Management::Deployment; + + PackageManager packageManager; + + for (auto const& package : packageManager.FindPackagesForUser({})) + { + const auto& packageFullName = std::wstring{ package.Id().FullName() }; + + if (packageFullName.contains(packageDisplayName)) + { + return true; + } + } + + return false; + } + + inline bool RegisterSparsePackage(std::wstring externalLocation, std::wstring sparsePkgPath) + { + using namespace winrt::Windows::Foundation; + using namespace winrt::Windows::Management::Deployment; + + try + { + Uri externalUri{ externalLocation }; + Uri packageUri{ sparsePkgPath }; + + PackageManager packageManager; + + // Declare use of an external location + AddPackageOptions options; + options.ExternalLocationUri(externalUri); + + IAsyncOperationWithProgress deploymentOperation = packageManager.AddPackageByUriAsync(packageUri, options); + deploymentOperation.get(); + + // Check the status of the operation + if (deploymentOperation.Status() == AsyncStatus::Error) + { + auto deploymentResult{ deploymentOperation.GetResults() }; + auto errorCode = deploymentOperation.ErrorCode(); + auto errorText = deploymentResult.ErrorText(); + + Logger::error(L"Register {} package failed. ErrorCode: {}, ErrorText: {}", sparsePkgPath, std::to_wstring(errorCode), errorText); + return false; + } + else if (deploymentOperation.Status() == AsyncStatus::Canceled) + { + Logger::error(L"Register {} package canceled.", sparsePkgPath); + return false; + } + else if (deploymentOperation.Status() == AsyncStatus::Completed) + { + Logger::info(L"Register {} package completed.", sparsePkgPath); + } + else + { + Logger::debug(L"Register {} package started.", sparsePkgPath); + } + + return true; + } + catch (std::exception e) + { + Logger::error("Exception thrown while trying to register package: {}", e.what()); + + return false; + } + } +} \ No newline at end of file diff --git a/src/logging/logging.vcxproj b/src/logging/logging.vcxproj index 6f10fa2a2c..3f39a7e647 100644 --- a/src/logging/logging.vcxproj +++ b/src/logging/logging.vcxproj @@ -30,7 +30,7 @@ {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F} Win32Proj spdlog - 10.0.18362.0 + 10.0.19041.0 diff --git a/src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj b/src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj index 49de3b5068..270ce488e9 100644 --- a/src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj +++ b/src/modules/MouseUtils/FindMyMouse/FindMyMouse.vcxproj @@ -7,7 +7,7 @@ Win32Proj FindMyMouse true - 10.0.18362.0 + 10.0.19041.0 FindMyMouse diff --git a/src/modules/MouseUtils/MouseHighlighter/MouseHighlighter.vcxproj b/src/modules/MouseUtils/MouseHighlighter/MouseHighlighter.vcxproj index 84e8024636..e6247ea4d8 100644 --- a/src/modules/MouseUtils/MouseHighlighter/MouseHighlighter.vcxproj +++ b/src/modules/MouseUtils/MouseHighlighter/MouseHighlighter.vcxproj @@ -6,7 +6,7 @@ {782a61be-9d85-4081-b35c-1ccc9dcc1e88} Win32Proj MouseHighlighter - 10.0.18362.0 + 10.0.19041.0 MouseHighlighter diff --git a/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj b/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj index d441927e78..7a37790a16 100644 --- a/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj +++ b/src/modules/MouseUtils/MousePointerCrosshairs/MousePointerCrosshairs.vcxproj @@ -6,7 +6,7 @@ {eae14c0e-7a6b-45da-9080-a7d8c077ba6e} Win32Proj MousePointerCrosshairs - 10.0.18362.0 + 10.0.19041.0 MousePointerCrosshairs diff --git a/src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj b/src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj index 8a193062f8..37cb052b6b 100644 --- a/src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj +++ b/src/modules/ShortcutGuide/ShortcutGuide/ShortcutGuide.vcxproj @@ -13,7 +13,7 @@ {2edb3eb4-fa92-4bff-b2d8-566584837231} Win32Proj ShortcutGuide - 10.0.18362.0 + 10.0.19041.0 diff --git a/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.vcxproj b/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.vcxproj index 2b5fcb3536..0dc1707709 100644 --- a/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.vcxproj +++ b/src/modules/ShortcutGuide/ShortcutGuideModuleInterface/ShortcutGuideModuleInterface.vcxproj @@ -9,7 +9,7 @@ Win32Proj {2d604c07-51fc-46bb-9eb7-75aecc7f5e81} ShortcutGuideModuleInterface - 10.0.18362.0 + 10.0.19041.0 ShortcutGuideModuleInterface diff --git a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj index dda951dee6..f06126b3fb 100644 --- a/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj +++ b/src/modules/alwaysontop/AlwaysOnTop/AlwaysOnTop.vcxproj @@ -56,7 +56,7 @@ - 10.0.18362.0 + 10.0.19041.0 16.0 Win32Proj {1DC3BE92-CE89-43FB-8110-9C043A2FE7A2} diff --git a/src/modules/awake/Awake/Awake.csproj b/src/modules/awake/Awake/Awake.csproj index 4750822e66..eab00b6914 100644 --- a/src/modules/awake/Awake/Awake.csproj +++ b/src/modules/awake/Awake/Awake.csproj @@ -2,7 +2,7 @@ WinExe - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 win-x64;win-arm64 $(SolutionDir)$(Platform)\$(Configuration)\modules\Awake enable @@ -14,7 +14,7 @@ PowerToys.Awake $(Version).0 Images\Awake.ico - 10.0.18362.0 + 10.0.19041.0 https://awake.den.dev https://github.com/microsoft/powertoys true diff --git a/src/modules/awake/AwakeModuleInterface/AwakeModuleInterface.vcxproj b/src/modules/awake/AwakeModuleInterface/AwakeModuleInterface.vcxproj index 8e3bea3abf..ec63f98a90 100644 --- a/src/modules/awake/AwakeModuleInterface/AwakeModuleInterface.vcxproj +++ b/src/modules/awake/AwakeModuleInterface/AwakeModuleInterface.vcxproj @@ -7,7 +7,7 @@ Win32Proj Awake AwakeModuleInterface - 10.0.18362.0 + 10.0.19041.0 PowerToys.AwakeModuleInterface v143 diff --git a/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj b/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj index bb95126261..2f3a71065d 100644 --- a/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj +++ b/src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj @@ -15,7 +15,7 @@ WinExe ColorPicker PowerToys.ColorPickerUI - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 8.0 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} diff --git a/src/modules/colorPicker/UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj b/src/modules/colorPicker/UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj index 73b4136981..71653066af 100644 --- a/src/modules/colorPicker/UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj +++ b/src/modules/colorPicker/UnitTest-ColorPickerUI/UnitTest-ColorPickerUI.csproj @@ -2,7 +2,7 @@ - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {090CD7B7-3B0C-4D1D-BC98-83EB5D799BC1} Microsoft.ColorPicker.UnitTests false diff --git a/src/modules/fancyzones/FancyZones/FancyZones.vcxproj b/src/modules/fancyzones/FancyZones/FancyZones.vcxproj index 590f49e11b..c5adb38b94 100644 --- a/src/modules/fancyzones/FancyZones/FancyZones.vcxproj +++ b/src/modules/fancyzones/FancyZones/FancyZones.vcxproj @@ -56,7 +56,7 @@ - 10.0.18362.0 + 10.0.19041.0 16.0 Win32Proj {ff1d7936-842a-4bbb-8bea-e9fe796de700} diff --git a/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj b/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj index 2a3efeb03e..abda11ccae 100644 --- a/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj +++ b/src/modules/fancyzones/FancyZonesTests/UnitTests/UnitTests.vcxproj @@ -8,7 +8,7 @@ UnitTests NativeUnitTestProject UnitTests-FancyZones - 10.0.18362.0 + 10.0.19041.0 diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj index a038d23ec0..0dc3066c40 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj +++ b/src/modules/fancyzones/editor/FancyZonesEditor/FancyZonesEditor.csproj @@ -16,7 +16,7 @@ {5CCC8468-DEC8-4D36-99D4-5C891BEBD481} - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} true $(SolutionDir)$(Platform)\$(Configuration)\obj\$(AssemblyName)\ diff --git a/src/modules/imageresizer/ImageResizerContextMenu/AppxManifest.xml b/src/modules/imageresizer/ImageResizerContextMenu/AppxManifest.xml new file mode 100644 index 0000000000..1483c9aa5e --- /dev/null +++ b/src/modules/imageresizer/ImageResizerContextMenu/AppxManifest.xml @@ -0,0 +1,55 @@ + + + + + Microsoft.PowerToys.ImageResizerContextMenu + Microsoft + Assets\storelogo.png + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/imageresizer/ImageResizerContextMenu/Assets/LargeTile.png b/src/modules/imageresizer/ImageResizerContextMenu/Assets/LargeTile.png new file mode 100644 index 0000000000000000000000000000000000000000..53ee3777ea27e31b260014cf4074099874ff933a GIT binary patch literal 1755 zcmZvde@q)?7{{+i3tS0qt7{iJ0{^s_^@sZdMMEaBz#P|xjghsxG)6Bvp>vyv%aSq0 z)njao1dV0XNw&c@qmj1e*jgQ$l@_urW5G4RSY#rT1z`#%3;{EB`aJK|TH^lb_3nAT z-_Q4X-(K&IS8UyqsnjYdippfmN-HT!X2MT;Dpcy~-#$k6V z|MR4vU#O&p7TC46pTflb3 zoUJ;ZRf#&8&EwXy5s%!&(q6cN62swD#FH%O-RJsjWPZN3^^@FCIQ&MxXIFo7!I#VI zkpIstuWqUV5uhgs07?k$*!`uiZ=5b#$lI|0c+XJvj(}zSE3MN#EyOK zql(#yA}~Ibl*r(s1}Z^5mmn*-n93g?-ccM+^PN?6HH~h0hjy6@XY*^i<-V)+OZ;p7 z7j`p_sT55xnYsedNIIel^QIIg7i@`2Qi}x5$!tk29$2OQI zs^kQXAKE}5ZJu$)2@Dxn?}}O@f@6@^!%9Tj+o>=jd!^ZuvBE4jb4g}Z5WMBtcmy^~ zoFGVS5|0FA!(1Q%fL?Bj*L+9ZL{mjSO8lzqrQ0UCZ)X zPwk$1HNFgaK%NxGpuXz}#ywXvf2JQ?BQ5uOZM2up4S#ieaxS$!o9o6Z=czNQb} zwAh|xLZ>+WyN%o?^uCAQw&&4o?S$DJ`WP(Hr*grL*qNXlqU0osCQ(Up5F(^$Z5;n&oJIO4uF`k&QL*j{f zU=;#MZ5{@b%qMbjTB3dh-5#mqY>%{0jgS+WdHyG literal 0 HcmV?d00001 diff --git a/src/modules/imageresizer/ImageResizerContextMenu/Assets/SmallTile.png b/src/modules/imageresizer/ImageResizerContextMenu/Assets/SmallTile.png new file mode 100644 index 0000000000000000000000000000000000000000..f713bba67f551ef91020b75716a4dc8ebd744b1c GIT binary patch literal 637 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 HPwYPdb)5xk literal 0 HcmV?d00001 diff --git a/src/modules/imageresizer/ImageResizerContextMenu/Assets/Square150x150Logo.png b/src/modules/imageresizer/ImageResizerContextMenu/Assets/Square150x150Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..53ee3777ea27e31b260014cf4074099874ff933a GIT binary patch literal 1755 zcmZvde@q)?7{{+i3tS0qt7{iJ0{^s_^@sZdMMEaBz#P|xjghsxG)6Bvp>vyv%aSq0 z)njao1dV0XNw&c@qmj1e*jgQ$l@_urW5G4RSY#rT1z`#%3;{EB`aJK|TH^lb_3nAT z-_Q4X-(K&IS8UyqsnjYdippfmN-HT!X2MT;Dpcy~-#$k6V z|MR4vU#O&p7TC46pTflb3 zoUJ;ZRf#&8&EwXy5s%!&(q6cN62swD#FH%O-RJsjWPZN3^^@FCIQ&MxXIFo7!I#VI zkpIstuWqUV5uhgs07?k$*!`uiZ=5b#$lI|0c+XJvj(}zSE3MN#EyOK zql(#yA}~Ibl*r(s1}Z^5mmn*-n93g?-ccM+^PN?6HH~h0hjy6@XY*^i<-V)+OZ;p7 z7j`p_sT55xnYsedNIIel^QIIg7i@`2Qi}x5$!tk29$2OQI zs^kQXAKE}5ZJu$)2@Dxn?}}O@f@6@^!%9Tj+o>=jd!^ZuvBE4jb4g}Z5WMBtcmy^~ zoFGVS5|0FA!(1Q%fL?Bj*L+9ZL{mjSO8lzqrQ0UCZ)X zPwk$1HNFgaK%NxGpuXz}#ywXvf2JQ?BQ5uOZM2up4S#ieaxS$!o9o6Z=czNQb} zwAh|xLZ>+WyN%o?^uCAQw&&4o?S$DJ`WP(Hr*grL*qNXlqU0osCQ(Up5F(^$Z5;n&oJIO4uF`k&QL*j{f zU=;#MZ5{@b%qMbjTB3dh-5#mqY>%{0jgS+WdHyG literal 0 HcmV?d00001 diff --git a/src/modules/imageresizer/ImageResizerContextMenu/Assets/Square44x44Logo.png b/src/modules/imageresizer/ImageResizerContextMenu/Assets/Square44x44Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f713bba67f551ef91020b75716a4dc8ebd744b1c GIT binary patch literal 637 zcmeAS@N?(olHy`uVBq!ia0vp^5g^RL1|$oo8kjIJFu8cTIEGZ*dUI*J;2{SImxtDO zm%3!R$UazoY}x{$j0P5ABYXWr(l=jxJ6ps1W{tV=^>{Dl><3nv3A}sm=EZ)#l3`NR zpZda3^rNox*D1%NC98Z~L*6zipLw~Gxn&(Y-;KmJ+aR6eLabU-L#y8HW%7P-E_-VlLqIabbHPHKT*)fT@9iWJ7iWgOT9%0}Lrj>lztPxWq6sPw3pi z#-<=#$jjrP_DD*i!RLsn0mIA=>4~N)IMYWIf=j%-zuKCdMG%tHYot70D1| zvWa0wMhauW#S>1CnI_;>!1Q3zMA17@DOVq{MQ+{U7^a&yA+%dMCG;WNPV0i;w$tu; zX^b}UKziPM)(<;)ruW;-`)bBN+rQNM*Zs_>?n$|FVFo-e*PZb*@U7VAd+tHb4ec0sq%A~kJcD9FY~qQRMt?ZR3YyDZt}Od;|mgpc{2dv9AHF){kXU%k({ z=Y8JidEayHTkG@twPZ|U3_^%3ct-OgLSiFAqDN!|tbCX@c@?4P`2x*TMK!+Q4b?k0 ziW7!!KF6dPWcF<%I|iznM~`QJ_V7sHGV_D`dhgpA9Vd@&X}ErK+j~_rdv;Bp?OA@a zFXOk7eWOJe5NcK;6h$FaM&7JxNc#-@QTwzW6x#d_zmQNkz5) zPI;kh;3d;5UCJU+9a(cOxX(|edWoOiAEdGU#kPJ&xnc2||3vDbuhBCkj-pb0as$Zl z5;}4n=**n6(1g`JEtSy;SG6X;#-F~Oz3lESG2b5`j@wAwY4Yp<=4Xeb>iH=6aicF?DxD&q{`!&}ct zBI)aycwuobQAf&678Uf+Mmh-@9RUhyH~>?w0dixO0#jZjEc9R^=5NZw=|a(kcB?9^ zfnTiEFXp-q#B;Tn>(O%$A*ud^Rg&eVH6Y_5Y%!E39RR&s?XpG`gKwU!6FE1 z7X)DC7)*(5g}lh`4`{i~DZcWupZI`K)_4P)VE{@gc7@Xsd^86zl~_mOYH?I4!aGeX z^E(_=L6?PgveDQ+r%P@UISEXrkn`LHJZ##+!-anV>6h)IkKp;E@p8+3&(5%kS2)ld*J*rJccZM0iyaAx7+F~GW1UWFK&3X$PE1^}NH zgAG9ck5K!{07OwU@j@Do>TbH=CDEo#4m0cEyAuXy_<&jlzJVcKweSJ5 z&=q~iIn18$w8yb=rmEmHxVEUA^?RwnB?6Qlp1os8@*dWTGL2bhzZ!s*xqScR?EPL` zo(JwNdKUUYy7GtvZ3asXm)cgFvCx9EmAi;|w=a0iGiv%%VYKh`P0Wma4y`Xyx|T~( zAmfGbgbEEC7)j8b@WA@+5W3a61HJXC1dX@6_T|Czk0I0zBk%tnW~()VWITGI!`$c< gARL?UBrYYkwoDw4eo*CrzXGTrZ@;GF>596)00d&n@&Et; literal 0 HcmV?d00001 diff --git a/src/modules/imageresizer/ImageResizerContextMenu/Assets/storelogo.png b/src/modules/imageresizer/ImageResizerContextMenu/Assets/storelogo.png new file mode 100644 index 0000000000000000000000000000000000000000..a4586f26bdf7841cad10f39cdffe2aca3af252c1 GIT binary patch literal 456 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 +#include "Generated Files/resource.h" +#include "../../../../common/version/version.h" + +#define APSTUDIO_READONLY_SYMBOLS +#include "winres.h" +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION FILE_VERSION + PRODUCTVERSION PRODUCT_VERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + 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 + END +END diff --git a/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj b/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj new file mode 100644 index 0000000000..1b6640d617 --- /dev/null +++ b/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj @@ -0,0 +1,135 @@ + + + + + + + + Win32Proj + {93b72a06-c8bd-484f-a6f7-c9f280b150bf} + ImageResizerContextMenu + + + + DynamicLibrary + true + v143 + + + DynamicLibrary + false + v143 + true + + + + + + + + + + + + PowerToys.ImageResizerContextMenu + $(SolutionDir)$(Platform)\$(Configuration)\modules\ImageResizer\ + + + + Level3 + true + _DEBUG;IMAGERESIZERCONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + ..\ImageResizerLib;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + + + Windows + true + false + Source.def + + + del $(OutDir)*.msix /q +MakeAppx.exe pack /d . /p $(OutDir)ImageResizerContextMenuPackage.msix /nv + + + + + Level3 + true + true + true + NDEBUG;IMAGERESIZERCONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + ..\ImageResizerLib;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + false + Source.def + + + del $(OutDir)*.msix /q +MakeAppx.exe pack /d . /p $(OutDir)ImageResizerContextMenuPackage.msix /nv + + + + + + + + + + + + + Create + + + + + + + + + + + + + + + + + + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} + + + {6955446d-23f7-4023-9bb3-8657f904af99} + + + {18b3db45-4ffe-4d01-97d6-5223feee1853} + + + + + + + + + + + + + + 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}. + + + + + + \ No newline at end of file diff --git a/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj.filters b/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj.filters new file mode 100644 index 0000000000..c0260dea28 --- /dev/null +++ b/src/modules/imageresizer/ImageResizerContextMenu/ImageResizerContextMenu.vcxproj.filters @@ -0,0 +1,59 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + + + Resource Files + + + Resource Files + + + + Header Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/src/modules/imageresizer/ImageResizerContextMenu/Resources.resx b/src/modules/imageresizer/ImageResizerContextMenu/Resources.resx new file mode 100644 index 0000000000..f72fd33367 --- /dev/null +++ b/src/modules/imageresizer/ImageResizerContextMenu/Resources.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Resize pictures + + + Image Resizer + + \ No newline at end of file diff --git a/src/modules/imageresizer/ImageResizerContextMenu/Source.def b/src/modules/imageresizer/ImageResizerContextMenu/Source.def new file mode 100644 index 0000000000..1ffdadd7a1 --- /dev/null +++ b/src/modules/imageresizer/ImageResizerContextMenu/Source.def @@ -0,0 +1,5 @@ +LIBRARY +EXPORTS +DllCanUnloadNow PRIVATE +DllGetClassObject PRIVATE +DllGetActivationFactory PRIVATE \ No newline at end of file diff --git a/src/modules/imageresizer/ImageResizerContextMenu/dllmain.cpp b/src/modules/imageresizer/ImageResizerContextMenu/dllmain.cpp new file mode 100644 index 0000000000..d818188c6a --- /dev/null +++ b/src/modules/imageresizer/ImageResizerContextMenu/dllmain.cpp @@ -0,0 +1,272 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include "pch.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include "Generated Files/resource.h" + +using namespace Microsoft::WRL; + +HINSTANCE g_hInst = 0; + +#define BUFSIZE 4096 * 4 + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + g_hInst = hModule; + Trace::RegisterProvider(); + break; + case DLL_PROCESS_DETACH: + Trace::UnregisterProvider(); + break; + } + return TRUE; +} + +class __declspec(uuid("8F491918-259F-451A-950F-8C3EBF4864AF")) ImageResizerContextMenuCommand final : public RuntimeClass, IExplorerCommand, IObjectWithSite> +{ +public: + virtual const wchar_t* Title() { return L"Image Resizer"; } + virtual const EXPCMDFLAGS Flags() { return ECF_DEFAULT; } + virtual const EXPCMDSTATE State(_In_opt_ IShellItemArray* selection) { return ECS_ENABLED; } + + // IExplorerCommand + IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name) + { + wchar_t strResizePictures[64] = { 0 }; + LoadString(g_hInst, IDS_RESIZE_PICTURES_TITLE, strResizePictures, ARRAYSIZE(strResizePictures)); + + return SHStrDup(strResizePictures, name); + } + + IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* icon) + { + std::wstring iconResourcePath = get_module_folderpath(g_hInst); + iconResourcePath += L"\\"; + iconResourcePath += L"ImageResizer.ico"; + return SHStrDup(iconResourcePath.c_str(), icon); + } + + IFACEMETHODIMP GetToolTip(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* infoTip) + { + *infoTip = nullptr; + return E_NOTIMPL; + } + + IFACEMETHODIMP GetCanonicalName(_Out_ GUID* guidCommandName) + { + *guidCommandName = __uuidof(this); + return S_OK; + } + + IFACEMETHODIMP GetState(_In_opt_ IShellItemArray* selection, _In_ BOOL okToBeSlow, _Out_ EXPCMDSTATE* cmdState) + { + if (!CSettingsInstance().GetEnabled()) + { + *cmdState = ECS_HIDDEN; + return S_OK; + } + // Hide if the file is not an image + *cmdState = ECS_HIDDEN; + // Suppressing C26812 warning as the issue is in the shtypes.h library +#pragma warning(suppress : 26812) + PERCEIVED type; + PERCEIVEDFLAG flag; + IShellItem* shellItem; + //Check extension of first item in the list (the item which is right-clicked on) + selection->GetItemAt(0, &shellItem); + LPTSTR pszPath; + // Retrieves the entire file system path of the file from its shell item + shellItem->GetDisplayName(SIGDN_FILESYSPATH, &pszPath); + LPTSTR pszExt = PathFindExtension(pszPath); + + // TODO: Instead, detect whether there's a WIC codec installed that can handle this file + AssocGetPerceivedType(pszExt, &type, &flag, NULL); + + CoTaskMemFree(pszPath); + // If selected file is an image... + + if (type == PERCEIVED_TYPE_IMAGE) + { + *cmdState = ECS_ENABLED; + } + return S_OK; + } + + IFACEMETHODIMP Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept + try + { + + Trace::Invoked(); + HRESULT hr = S_OK; + + if (selection) + { + hr = ResizePictures(selection); + } + + Trace::InvokedRet(hr); + + return hr; + } + CATCH_RETURN(); + + IFACEMETHODIMP GetFlags(_Out_ EXPCMDFLAGS* flags) + { + *flags = Flags(); + return S_OK; + } + IFACEMETHODIMP EnumSubCommands(_COM_Outptr_ IEnumExplorerCommand** enumCommands) + { + *enumCommands = nullptr; + return E_NOTIMPL; + } + + // IObjectWithSite + IFACEMETHODIMP SetSite(_In_ IUnknown* site) noexcept + { + m_site = site; + return S_OK; + } + IFACEMETHODIMP GetSite(_In_ REFIID riid, _COM_Outptr_ void** site) noexcept { return m_site.CopyTo(riid, site); } + +protected: + ComPtr m_site; + +private: + HRESULT StartNamedPipeServerAndSendData(std::wstring pipe_name) + { + hPipe = CreateNamedPipe( + pipe_name.c_str(), + PIPE_ACCESS_DUPLEX | + WRITE_DAC, + PIPE_TYPE_MESSAGE | + PIPE_READMODE_MESSAGE | + PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, + BUFSIZE, + BUFSIZE, + 0, + NULL); + + if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE) + { + return E_FAIL; + } + + // This call blocks until a client process connects to the pipe + BOOL connected = ConnectNamedPipe(hPipe, NULL); + if (!connected) + { + if (GetLastError() == ERROR_PIPE_CONNECTED) + { + return S_OK; + } + else + { + CloseHandle(hPipe); + } + return E_FAIL; + } + + return S_OK; + } + + HRESULT ResizePictures(IShellItemArray* psiItemArray) + { + // Set the application path based on the location of the dll + std::wstring path = get_module_folderpath(g_hInst); + path = path + L"\\PowerToys.ImageResizer.exe"; + + std::wstring pipe_name(L"\\\\.\\pipe\\powertoys_imageresizerinput_"); + UUID temp_uuid; + wchar_t* uuid_chars = nullptr; + if (UuidCreate(&temp_uuid) == RPC_S_UUID_NO_ADDRESS) + { + auto val = get_last_error_message(GetLastError()); + Logger::warn(L"UuidCreate can not create guid. {}", val.has_value() ? val.value() : L""); + } + else if (UuidToString(&temp_uuid, (RPC_WSTR*)&uuid_chars) != RPC_S_OK) + { + auto val = get_last_error_message(GetLastError()); + Logger::warn(L"UuidToString can not convert to string. {}", val.has_value() ? val.value() : L""); + } + + if (uuid_chars != nullptr) + { + pipe_name += std::wstring(uuid_chars); + RpcStringFree((RPC_WSTR*)&uuid_chars); + uuid_chars = nullptr; + } + create_pipe_thread = std::thread(&ImageResizerContextMenuCommand::StartNamedPipeServerAndSendData, this, pipe_name); + RunNonElevatedEx(path.c_str(), pipe_name, get_module_folderpath(g_hInst)); + create_pipe_thread.join(); + + if (hPipe != INVALID_HANDLE_VALUE) + { + CAtlFile writePipe(hPipe); + + //m_pdtobj will be NULL when invoked from the MSIX build as Initialize is never called (IShellExtInit functions aren't called in case of MSIX). + DWORD fileCount = 0; + // Gets the list of files currently selected using the IShellItemArray + psiItemArray->GetCount(&fileCount); + // Iterate over the list of files + for (DWORD i = 0; i < fileCount; i++) + { + IShellItem* shellItem; + psiItemArray->GetItemAt(i, &shellItem); + LPWSTR itemName; + // Retrieves the entire file system path of the file from its shell item + shellItem->GetDisplayName(SIGDN_FILESYSPATH, &itemName); + CString fileName(itemName); + fileName.Append(_T("\r\n")); + // Write the file path into the input stream for image resizer + writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR)); + } + writePipe.Close(); + } + + return S_OK; + } + + std::thread create_pipe_thread; + HANDLE hPipe = INVALID_HANDLE_VALUE; + std::wstring app_name = L"ImageResizer"; +}; + +CoCreatableClass(ImageResizerContextMenuCommand) +CoCreatableClassWrlCreatorMapInclude(ImageResizerContextMenuCommand) + + +STDAPI DllGetActivationFactory(_In_ HSTRING activatableClassId, _COM_Outptr_ IActivationFactory** factory) +{ + return Module::GetModule().GetActivationFactory(activatableClassId, factory); +} + +STDAPI DllCanUnloadNow() +{ + return Module::GetModule().GetObjectCount() == 0 ? S_OK : S_FALSE; +} + +STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _COM_Outptr_ void** instance) +{ + return Module::GetModule().GetClassObject(rclsid, riid, instance); +} diff --git a/src/modules/imageresizer/ImageResizerContextMenu/framework.h b/src/modules/imageresizer/ImageResizerContextMenu/framework.h new file mode 100644 index 0000000000..54b83e94fd --- /dev/null +++ b/src/modules/imageresizer/ImageResizerContextMenu/framework.h @@ -0,0 +1,5 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files +#include diff --git a/src/modules/imageresizer/ImageResizerContextMenu/packages.config b/src/modules/imageresizer/ImageResizerContextMenu/packages.config new file mode 100644 index 0000000000..ed327ca35a --- /dev/null +++ b/src/modules/imageresizer/ImageResizerContextMenu/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/modules/imageresizer/ImageResizerContextMenu/pch.cpp b/src/modules/imageresizer/ImageResizerContextMenu/pch.cpp new file mode 100644 index 0000000000..64b7eef6d6 --- /dev/null +++ b/src/modules/imageresizer/ImageResizerContextMenu/pch.cpp @@ -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. diff --git a/src/modules/imageresizer/ImageResizerContextMenu/pch.h b/src/modules/imageresizer/ImageResizerContextMenu/pch.h new file mode 100644 index 0000000000..885d5d62e4 --- /dev/null +++ b/src/modules/imageresizer/ImageResizerContextMenu/pch.h @@ -0,0 +1,13 @@ +// 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 + +// add headers that you want to pre-compile here +#include "framework.h" + +#endif //PCH_H diff --git a/src/modules/imageresizer/ImageResizerContextMenu/resource.base.h b/src/modules/imageresizer/ImageResizerContextMenu/resource.base.h new file mode 100644 index 0000000000..b362797710 --- /dev/null +++ b/src/modules/imageresizer/ImageResizerContextMenu/resource.base.h @@ -0,0 +1,13 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by ImageResizerContextMenu.rc + +////////////////////////////// +// Non-localizable + +#define FILE_DESCRIPTION "PowerToys Image Resizer Context Menu" +#define INTERNAL_NAME "PowerToys.ImageResizerContextMenu.dll" +#define ORIGINAL_FILENAME "PowerToys.ImageResizerContextMenu.dll" + +// Non-localizable +////////////////////////////// diff --git a/src/modules/imageresizer/ImageResizerContextMenu/targetver.h b/src/modules/imageresizer/ImageResizerContextMenu/targetver.h new file mode 100644 index 0000000000..1530e99ea6 --- /dev/null +++ b/src/modules/imageresizer/ImageResizerContextMenu/targetver.h @@ -0,0 +1,4 @@ +#pragma once + +#include +#include diff --git a/src/modules/imageresizer/dll/ImageResizerConstants.h b/src/modules/imageresizer/ImageResizerLib/ImageResizerConstants.h similarity index 100% rename from src/modules/imageresizer/dll/ImageResizerConstants.h rename to src/modules/imageresizer/ImageResizerLib/ImageResizerConstants.h diff --git a/src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj b/src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj new file mode 100644 index 0000000000..93350cf0db --- /dev/null +++ b/src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj @@ -0,0 +1,83 @@ + + + + Win32Proj + {18b3db45-4ffe-4d01-97d6-5223feee1853} + ImageResizerLib + 10.0.19041.0 + + + StaticLibrary + v143 + Unicode + + + + true + + + + false + true + + + + + + + + + + + $(SolutionDir)$(Platform)\$(Configuration)\modules\ImageResizer\ + + + PowerToys.$(ProjectName) + + + + Level3 + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + Use + ..\..\..\common\Telemetry;..\..\..\;%(AdditionalIncludeDirectories) + + + + + true + + + + + Level3 + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + Use + ..\..\..\common\Telemetry;..\..\..\;%(AdditionalIncludeDirectories) + + + + + true + true + true + + + + + + + + + + + + Create + + + + + + + \ No newline at end of file diff --git a/src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj.filters b/src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj.filters new file mode 100644 index 0000000000..e09410a77c --- /dev/null +++ b/src/modules/imageresizer/ImageResizerLib/ImageResizerLib.vcxproj.filters @@ -0,0 +1,45 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/src/modules/imageresizer/dll/Settings.cpp b/src/modules/imageresizer/ImageResizerLib/Settings.cpp similarity index 94% rename from src/modules/imageresizer/dll/Settings.cpp rename to src/modules/imageresizer/ImageResizerLib/Settings.cpp index f59eb5c86b..3631ebd68a 100644 --- a/src/modules/imageresizer/dll/Settings.cpp +++ b/src/modules/imageresizer/ImageResizerLib/Settings.cpp @@ -1,125 +1,125 @@ -#include "pch.h" -#include "Settings.h" - -#include -#include -#include -#include -#include - -namespace -{ - const wchar_t c_imageResizerDataFilePath[] = L"\\image-resizer-settings.json"; - const wchar_t c_rootRegPath[] = L"Software\\Microsoft\\ImageResizer"; - const wchar_t c_enabled[] = L"Enabled"; - - unsigned int RegReadInteger(const std::wstring& valueName, unsigned int defaultValue) - { - DWORD type = REG_DWORD; - DWORD data = 0; - DWORD size = sizeof(DWORD); - if (SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName.c_str(), &type, &data, &size) == ERROR_SUCCESS) - { - return data; - } - return defaultValue; - } - - bool RegReadBoolean(const std::wstring& valueName, bool defaultValue) - { - DWORD value = RegReadInteger(valueName.c_str(), defaultValue ? 1 : 0); - return (value == 0) ? false : true; - } - - bool LastModifiedTime(const std::wstring& filePath, FILETIME* lpFileTime) - { - WIN32_FILE_ATTRIBUTE_DATA attr{}; - if (GetFileAttributesExW(filePath.c_str(), GetFileExInfoStandard, &attr)) - { - *lpFileTime = attr.ftLastWriteTime; - return true; - } - return false; - } -} - -CSettings::CSettings() -{ - std::wstring oldSavePath = PTSettingsHelper::get_module_save_folder_location(ImageResizerConstants::ModuleOldSaveFolderKey); - std::wstring savePath = PTSettingsHelper::get_module_save_folder_location(ImageResizerConstants::ModuleSaveFolderKey); - std::error_code ec; - if (std::filesystem::exists(oldSavePath, ec)) - { - std::filesystem::copy(oldSavePath, savePath, std::filesystem::copy_options::recursive, ec); - std::filesystem::remove_all(oldSavePath, ec); - } - - jsonFilePath = savePath + std::wstring(c_imageResizerDataFilePath); - Load(); -} - -void CSettings::Save() -{ - json::JsonObject jsonData; - - jsonData.SetNamedValue(c_enabled, json::value(settings.enabled)); - - json::to_file(jsonFilePath, jsonData); - GetSystemTimeAsFileTime(&lastLoadedTime); -} - -void CSettings::Load() -{ - if (!std::filesystem::exists(jsonFilePath)) - { - MigrateFromRegistry(); - - Save(); - } - else - { - ParseJson(); - } -} - -void CSettings::Reload() -{ - // Load json settings from data file if it is modified in the meantime. - FILETIME lastModifiedTime{}; - if (LastModifiedTime(jsonFilePath, &lastModifiedTime) && - CompareFileTime(&lastModifiedTime, &lastLoadedTime) == 1) - { - Load(); - } -} - -void CSettings::MigrateFromRegistry() -{ - settings.enabled = RegReadBoolean(c_enabled, true); -} - -void CSettings::ParseJson() -{ - auto json = json::from_file(jsonFilePath); - if (json) - { - const json::JsonObject& jsonSettings = json.value(); - try - { - if (json::has(jsonSettings, c_enabled, json::JsonValueType::Boolean)) - { - settings.enabled = jsonSettings.GetNamedBoolean(c_enabled); - } - } - catch (const winrt::hresult_error&) - { - } - } - GetSystemTimeAsFileTime(&lastLoadedTime); -} - -CSettings& CSettingsInstance() -{ - static CSettings instance; - return instance; +#include "pch.h" +#include "Settings.h" +#include "ImageResizerConstants.h" + +#include +#include +#include +#include + +namespace +{ + const wchar_t c_imageResizerDataFilePath[] = L"\\image-resizer-settings.json"; + const wchar_t c_rootRegPath[] = L"Software\\Microsoft\\ImageResizer"; + const wchar_t c_enabled[] = L"Enabled"; + + unsigned int RegReadInteger(const std::wstring& valueName, unsigned int defaultValue) + { + DWORD type = REG_DWORD; + DWORD data = 0; + DWORD size = sizeof(DWORD); + if (SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName.c_str(), &type, &data, &size) == ERROR_SUCCESS) + { + return data; + } + return defaultValue; + } + + bool RegReadBoolean(const std::wstring& valueName, bool defaultValue) + { + DWORD value = RegReadInteger(valueName.c_str(), defaultValue ? 1 : 0); + return (value == 0) ? false : true; + } + + bool LastModifiedTime(const std::wstring& filePath, FILETIME* lpFileTime) + { + WIN32_FILE_ATTRIBUTE_DATA attr{}; + if (GetFileAttributesExW(filePath.c_str(), GetFileExInfoStandard, &attr)) + { + *lpFileTime = attr.ftLastWriteTime; + return true; + } + return false; + } +} + +CSettings::CSettings() +{ + std::wstring oldSavePath = PTSettingsHelper::get_module_save_folder_location(ImageResizerConstants::ModuleOldSaveFolderKey); + std::wstring savePath = PTSettingsHelper::get_module_save_folder_location(ImageResizerConstants::ModuleSaveFolderKey); + std::error_code ec; + if (std::filesystem::exists(oldSavePath, ec)) + { + std::filesystem::copy(oldSavePath, savePath, std::filesystem::copy_options::recursive, ec); + std::filesystem::remove_all(oldSavePath, ec); + } + + jsonFilePath = savePath + std::wstring(c_imageResizerDataFilePath); + Load(); +} + +void CSettings::Save() +{ + json::JsonObject jsonData; + + jsonData.SetNamedValue(c_enabled, json::value(settings.enabled)); + + json::to_file(jsonFilePath, jsonData); + GetSystemTimeAsFileTime(&lastLoadedTime); +} + +void CSettings::Load() +{ + if (!std::filesystem::exists(jsonFilePath)) + { + MigrateFromRegistry(); + + Save(); + } + else + { + ParseJson(); + } +} + +void CSettings::Reload() +{ + // Load json settings from data file if it is modified in the meantime. + FILETIME lastModifiedTime{}; + if (LastModifiedTime(jsonFilePath, &lastModifiedTime) && + CompareFileTime(&lastModifiedTime, &lastLoadedTime) == 1) + { + Load(); + } +} + +void CSettings::MigrateFromRegistry() +{ + settings.enabled = RegReadBoolean(c_enabled, true); +} + +void CSettings::ParseJson() +{ + auto json = json::from_file(jsonFilePath); + if (json) + { + const json::JsonObject& jsonSettings = json.value(); + try + { + if (json::has(jsonSettings, c_enabled, json::JsonValueType::Boolean)) + { + settings.enabled = jsonSettings.GetNamedBoolean(c_enabled); + } + } + catch (const winrt::hresult_error&) + { + } + } + GetSystemTimeAsFileTime(&lastLoadedTime); +} + +CSettings& CSettingsInstance() +{ + static CSettings instance; + return instance; } \ No newline at end of file diff --git a/src/modules/imageresizer/dll/Settings.h b/src/modules/imageresizer/ImageResizerLib/Settings.h similarity index 93% rename from src/modules/imageresizer/dll/Settings.h rename to src/modules/imageresizer/ImageResizerLib/Settings.h index f0b51861df..aaff4793b7 100644 --- a/src/modules/imageresizer/dll/Settings.h +++ b/src/modules/imageresizer/ImageResizerLib/Settings.h @@ -1,38 +1,38 @@ -#pragma once - -class CSettings -{ -public: - CSettings(); - - inline bool GetEnabled() - { - Reload(); - return settings.enabled; - } - - inline void SetEnabled(bool enabled) - { - settings.enabled = enabled; - Save(); - } - - void Save(); - void Load(); - -private: - struct Settings - { - bool enabled{ true }; - }; - - void Reload(); - void MigrateFromRegistry(); - void ParseJson(); - - Settings settings; - std::wstring jsonFilePath; - FILETIME lastLoadedTime; -}; - +#pragma once + +class CSettings +{ +public: + CSettings(); + + inline bool GetEnabled() + { + Reload(); + return settings.enabled; + } + + inline void SetEnabled(bool enabled) + { + settings.enabled = enabled; + Save(); + } + + void Save(); + void Load(); + +private: + struct Settings + { + bool enabled{ true }; + }; + + void Reload(); + void MigrateFromRegistry(); + void ParseJson(); + + Settings settings; + std::wstring jsonFilePath; + FILETIME lastLoadedTime; +}; + CSettings& CSettingsInstance(); \ No newline at end of file diff --git a/src/modules/imageresizer/ImageResizerLib/framework.h b/src/modules/imageresizer/ImageResizerLib/framework.h new file mode 100644 index 0000000000..34edb144a5 --- /dev/null +++ b/src/modules/imageresizer/ImageResizerLib/framework.h @@ -0,0 +1,6 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +// Windows Header Files: +#include diff --git a/src/modules/imageresizer/ImageResizerLib/pch.cpp b/src/modules/imageresizer/ImageResizerLib/pch.cpp new file mode 100644 index 0000000000..64b7eef6d6 --- /dev/null +++ b/src/modules/imageresizer/ImageResizerLib/pch.cpp @@ -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. diff --git a/src/modules/imageresizer/ImageResizerLib/pch.h b/src/modules/imageresizer/ImageResizerLib/pch.h new file mode 100644 index 0000000000..dcca9b830b --- /dev/null +++ b/src/modules/imageresizer/ImageResizerLib/pch.h @@ -0,0 +1,18 @@ +// 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 + +// add headers that you want to pre-compile here +#include "framework.h" + +#include +#include + +#include + +#endif //PCH_H diff --git a/src/modules/imageresizer/dll/trace.cpp b/src/modules/imageresizer/ImageResizerLib/trace.cpp similarity index 96% rename from src/modules/imageresizer/dll/trace.cpp rename to src/modules/imageresizer/ImageResizerLib/trace.cpp index 84171932d0..352af3676a 100644 --- a/src/modules/imageresizer/dll/trace.cpp +++ b/src/modules/imageresizer/ImageResizerLib/trace.cpp @@ -1,59 +1,59 @@ -#include "pch.h" -#include "trace.h" - -TRACELOGGING_DEFINE_PROVIDER( - g_hProvider, - "Microsoft.PowerToys", - // {38e8889b-9731-53f5-e901-e8a7c1753074} - (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), - TraceLoggingOptionProjectTelemetry()); - -void Trace::RegisterProvider() noexcept -{ - TraceLoggingRegister(g_hProvider); -} - -void Trace::UnregisterProvider() noexcept -{ - TraceLoggingUnregister(g_hProvider); -} - -void Trace::EnableImageResizer(_In_ bool enabled) noexcept -{ - TraceLoggingWrite( - g_hProvider, - "ImageResizer_EnableImageResizer", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), - TraceLoggingBoolean(enabled, "Enabled")); -} - - -void Trace::Invoked() noexcept -{ - TraceLoggingWrite( - g_hProvider, - "ImageResizer_Invoked", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); -} - -void Trace::InvokedRet(_In_ HRESULT hr) noexcept -{ - TraceLoggingWrite( - g_hProvider, - "ImageResizer_InvokedRet", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingHResult(hr), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); -} - -void Trace::QueryContextMenuError(_In_ HRESULT hr) noexcept -{ - TraceLoggingWrite( - g_hProvider, - "ImageResizer_QueryContextMenuError", - ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), - TraceLoggingHResult(hr), - TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); -} +#include "pch.h" +#include "trace.h" + +TRACELOGGING_DEFINE_PROVIDER( + g_hProvider, + "Microsoft.PowerToys", + // {38e8889b-9731-53f5-e901-e8a7c1753074} + (0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74), + TraceLoggingOptionProjectTelemetry()); + +void Trace::RegisterProvider() noexcept +{ + TraceLoggingRegister(g_hProvider); +} + +void Trace::UnregisterProvider() noexcept +{ + TraceLoggingUnregister(g_hProvider); +} + +void Trace::EnableImageResizer(_In_ bool enabled) noexcept +{ + TraceLoggingWrite( + g_hProvider, + "ImageResizer_EnableImageResizer", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), + TraceLoggingBoolean(enabled, "Enabled")); +} + + +void Trace::Invoked() noexcept +{ + TraceLoggingWrite( + g_hProvider, + "ImageResizer_Invoked", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); +} + +void Trace::InvokedRet(_In_ HRESULT hr) noexcept +{ + TraceLoggingWrite( + g_hProvider, + "ImageResizer_InvokedRet", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingHResult(hr), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); +} + +void Trace::QueryContextMenuError(_In_ HRESULT hr) noexcept +{ + TraceLoggingWrite( + g_hProvider, + "ImageResizer_QueryContextMenuError", + ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), + TraceLoggingHResult(hr), + TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE)); +} diff --git a/src/modules/imageresizer/dll/trace.h b/src/modules/imageresizer/ImageResizerLib/trace.h similarity index 96% rename from src/modules/imageresizer/dll/trace.h rename to src/modules/imageresizer/ImageResizerLib/trace.h index 5f1bada262..9ff1e49f4e 100644 --- a/src/modules/imageresizer/dll/trace.h +++ b/src/modules/imageresizer/ImageResizerLib/trace.h @@ -1,12 +1,12 @@ -#pragma once - -class Trace -{ -public: - static void RegisterProvider() noexcept; - static void UnregisterProvider() noexcept; - static void EnableImageResizer(_In_ bool enabled) noexcept; - static void Invoked() noexcept; - static void InvokedRet(_In_ HRESULT hr) noexcept; - static void QueryContextMenuError(_In_ HRESULT hr) noexcept; +#pragma once + +class Trace +{ +public: + static void RegisterProvider() noexcept; + static void UnregisterProvider() noexcept; + static void EnableImageResizer(_In_ bool enabled) noexcept; + static void Invoked() noexcept; + static void InvokedRet(_In_ HRESULT hr) noexcept; + static void QueryContextMenuError(_In_ HRESULT hr) noexcept; }; \ No newline at end of file diff --git a/src/modules/imageresizer/dll/ContextMenuHandler.cpp b/src/modules/imageresizer/dll/ContextMenuHandler.cpp index 9d86398ae1..3296c1c91c 100644 --- a/src/modules/imageresizer/dll/ContextMenuHandler.cpp +++ b/src/modules/imageresizer/dll/ContextMenuHandler.cpp @@ -2,13 +2,15 @@ #include "pch.h" #include "ContextMenuHandler.h" -#include "Settings.h" + +#include +#include + #include #include #include #include - -#include "trace.h" +#include extern HINSTANCE g_hInst_imageResizer; @@ -61,6 +63,9 @@ HRESULT CContextMenuHandler::Initialize(_In_opt_ PCIDLIST_ABSOLUTE pidlFolder, _ HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) { + if (package::IsWin11OrGreater()) + return E_FAIL; + if (uFlags & CMF_DEFAULTONLY) { return S_OK; diff --git a/src/modules/imageresizer/dll/ImageResizerExt.vcxproj b/src/modules/imageresizer/dll/ImageResizerExt.vcxproj index acd2ee1868..c2f64e4ae0 100644 --- a/src/modules/imageresizer/dll/ImageResizerExt.vcxproj +++ b/src/modules/imageresizer/dll/ImageResizerExt.vcxproj @@ -32,7 +32,7 @@ _WINDOWS;_USRDLL;%(PreprocessorDefinitions) - ..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) + ..\ImageResizerLib;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories) .\ImageResizerExt.def @@ -89,23 +89,18 @@ - Create - - - - @@ -121,12 +116,18 @@ + + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} + {6955446d-23f7-4023-9bb3-8657f904af99} {98537082-0fdb-40de-abd8-0dc5a4269bab} + + {18b3db45-4ffe-4d01-97d6-5223feee1853} + @@ -135,6 +136,7 @@ + diff --git a/src/modules/imageresizer/dll/ImageResizerExt.vcxproj.filters b/src/modules/imageresizer/dll/ImageResizerExt.vcxproj.filters index dd6a23aa9a..d12fe0cf53 100644 --- a/src/modules/imageresizer/dll/ImageResizerExt.vcxproj.filters +++ b/src/modules/imageresizer/dll/ImageResizerExt.vcxproj.filters @@ -28,15 +28,6 @@ Source Files - - Source Files - - - Source Files - - - Header Files - Generated Files @@ -54,9 +45,6 @@ Header Files - - Header Files - Header Files @@ -66,9 +54,6 @@ Generated Files - - Header Files - diff --git a/src/modules/imageresizer/dll/dllmain.cpp b/src/modules/imageresizer/dll/dllmain.cpp index f369445c52..e622306e01 100644 --- a/src/modules/imageresizer/dll/dllmain.cpp +++ b/src/modules/imageresizer/dll/dllmain.cpp @@ -2,12 +2,18 @@ #include "Generated Files/resource.h" #include "ImageResizerExt_i.h" #include "dllmain.h" -#include + +#include +#include +#include + +#include #include +#include +#include #include -#include "Settings.h" -#include "trace.h" -#include +#include +#include CImageResizerExtModule _AtlModule; HINSTANCE g_hInst_imageResizer = 0; @@ -43,6 +49,7 @@ public: m_enabled = CSettingsInstance().GetEnabled(); app_name = GET_RESOURCE_STRING(IDS_IMAGERESIZER); app_key = ImageResizerConstants::ModuleKey; + LoggerHelpers::init_logger(app_key, L"ModuleInterface", LogSettings::imageResizerLoggerName); }; // Destroy the powertoy and free memory @@ -89,6 +96,20 @@ public: { m_enabled = true; CSettingsInstance().SetEnabled(m_enabled); + + if (package::IsWin11OrGreater()) + { + std::wstring path = get_module_folderpath(g_hInst_imageResizer); + std::wstring packageUri = path + L"\\ImageResizerContextMenuPackage.msix"; + + std::wstring packageDisplayName{ L"ImageResizerContextMenu" }; + if (!package::IsPackageRegistered(packageDisplayName)) + { + package::RegisterSparsePackage(path, packageUri); + } + } + + Trace::EnableImageResizer(m_enabled); } diff --git a/src/modules/imageresizer/tests/ImageResizerUITest.csproj b/src/modules/imageresizer/tests/ImageResizerUITest.csproj index 7c78ce1133..8e056e45e2 100644 --- a/src/modules/imageresizer/tests/ImageResizerUITest.csproj +++ b/src/modules/imageresizer/tests/ImageResizerUITest.csproj @@ -2,7 +2,7 @@ - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8} Library Properties diff --git a/src/modules/imageresizer/ui/ImageResizerUI.csproj b/src/modules/imageresizer/ui/ImageResizerUI.csproj index 77b2fac87d..b46119102f 100644 --- a/src/modules/imageresizer/ui/ImageResizerUI.csproj +++ b/src/modules/imageresizer/ui/ImageResizerUI.csproj @@ -15,7 +15,7 @@ WinExe ImageResizer PowerToys.ImageResizer - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} $(SolutionDir)$(Platform)\$(Configuration)\obj\$(AssemblyName)\ diff --git a/src/modules/imageresizer/ui/Models/ResizeBatch.cs b/src/modules/imageresizer/ui/Models/ResizeBatch.cs index f24b34ff55..0916961531 100644 --- a/src/modules/imageresizer/ui/Models/ResizeBatch.cs +++ b/src/modules/imageresizer/ui/Models/ResizeBatch.cs @@ -7,6 +7,8 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.IO.Abstractions; +using System.IO.Pipes; +using System.Text; using System.Threading; using System.Threading.Tasks; using ImageResizer.Properties; @@ -24,16 +26,8 @@ namespace ImageResizer.Models public static ResizeBatch FromCommandLine(TextReader standardInput, string[] args) { var batch = new ResizeBatch(); - - // NB: We read these from stdin since there are limits on the number of args you can have - string file; - if (standardInput != null) - { - while ((file = standardInput.ReadLine()) != null) - { - batch.Files.Add(file); - } - } + const string pipeNamePrefix = "\\\\.\\pipe\\"; + string pipeName = null; for (var i = 0; i < args?.Length; i++) { @@ -42,10 +36,48 @@ namespace ImageResizer.Models batch.DestinationDirectory = args[++i]; continue; } + else if (args[i].Contains(pipeNamePrefix)) + { + pipeName = args[i].Substring(pipeNamePrefix.Length); + continue; + } batch.Files.Add(args[i]); } + if (string.IsNullOrEmpty(pipeName)) + { + // NB: We read these from stdin since there are limits on the number of args you can have + string file; + if (standardInput != null) + { + while ((file = standardInput.ReadLine()) != null) + { + batch.Files.Add(file); + } + } + } + else + { + using (NamedPipeClientStream pipeClient = + new NamedPipeClientStream(".", pipeName, PipeDirection.In)) + { + // Connect to the pipe or wait until the pipe is available. + pipeClient.Connect(); + + using (StreamReader sr = new StreamReader(pipeClient, Encoding.Unicode)) + { + string file; + + // Display the read text to the console + while ((file = sr.ReadLine()) != null) + { + batch.Files.Add(file); + } + } + } + } + return batch; } diff --git a/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.exe.manifest b/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.exe.manifest index e70a561c0f..9f80c67839 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.exe.manifest +++ b/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.exe.manifest @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.vcxproj index fa4feb87cb..93758a4a27 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEditor/KeyboardManagerEditor.vcxproj @@ -64,8 +64,8 @@ {8df78b53-200e-451f-9328-01eb907193ae} KeyboardManagerEditor true - 10.0.18362.0 - 10.0.18362.0 + 10.0.19041.0 + 10.0.19041.0 diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/KeyboardManagerEditorLibrary.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/KeyboardManagerEditorLibrary.vcxproj index a66ece0e96..4d02bfd093 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/KeyboardManagerEditorLibrary.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEditorLibrary/KeyboardManagerEditorLibrary.vcxproj @@ -7,8 +7,8 @@ {23d2070d-e4ad-4add-85a7-083d9c76ad49} KeyboardManagerEditorLibrary true - 10.0.18362.0 - 10.0.18362.0 + 10.0.19041.0 + 10.0.19041.0 diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorTest/KeyboardManagerEditorTest.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEditorTest/KeyboardManagerEditorTest.vcxproj index 54ef1fdef2..6f77ed779d 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorTest/KeyboardManagerEditorTest.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEditorTest/KeyboardManagerEditorTest.vcxproj @@ -7,7 +7,7 @@ Win32Proj KeyboardManagerEditorTest true - 10.0.18362.0 + 10.0.19041.0 NativeUnitTestProject diff --git a/src/modules/keyboardmanager/KeyboardManagerEngine/KeyboardManagerEngine.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEngine/KeyboardManagerEngine.vcxproj index f69c7b75b7..aa874c2659 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngine/KeyboardManagerEngine.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEngine/KeyboardManagerEngine.vcxproj @@ -11,8 +11,8 @@ Win32Proj KeyboardManagerEngine true - 10.0.18362.0 - 10.0.18362.0 + 10.0.19041.0 + 10.0.19041.0 diff --git a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardManagerEngineLibrary.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardManagerEngineLibrary.vcxproj index 1b880b10a2..d6c6058b2a 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardManagerEngineLibrary.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardManagerEngineLibrary.vcxproj @@ -7,8 +7,8 @@ {e496b7fc-1e99-4bab-849b-0e8367040b02} KeyboardManagerEngineLibrary true - 10.0.18362.0 - 10.0.18362.0 + 10.0.19041.0 + 10.0.19041.0 diff --git a/src/modules/keyboardmanager/KeyboardManagerEngineTest/KeyboardManagerEngineTest.vcxproj b/src/modules/keyboardmanager/KeyboardManagerEngineTest/KeyboardManagerEngineTest.vcxproj index 630f6be05a..c7fb801d75 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEngineTest/KeyboardManagerEngineTest.vcxproj +++ b/src/modules/keyboardmanager/KeyboardManagerEngineTest/KeyboardManagerEngineTest.vcxproj @@ -7,7 +7,7 @@ Win32Proj KeyboardManagerEngineTest true - 10.0.18362.0 + 10.0.19041.0 NativeUnitTestProject KeyboardManagerEngineTest diff --git a/src/modules/keyboardmanager/common/KeyboardManagerCommon.vcxproj b/src/modules/keyboardmanager/common/KeyboardManagerCommon.vcxproj index 04fb18936d..0656e08b2a 100644 --- a/src/modules/keyboardmanager/common/KeyboardManagerCommon.vcxproj +++ b/src/modules/keyboardmanager/common/KeyboardManagerCommon.vcxproj @@ -6,7 +6,7 @@ {8AFFA899-0B73-49EC-8C50-0FADDA57B2FC} KeyboardManagerCommon true - 10.0.18362.0 + 10.0.19041.0 diff --git a/src/modules/keyboardmanager/dll/KeyboardManager.vcxproj b/src/modules/keyboardmanager/dll/KeyboardManager.vcxproj index 42be4a35bc..29e2a696ee 100644 --- a/src/modules/keyboardmanager/dll/KeyboardManager.vcxproj +++ b/src/modules/keyboardmanager/dll/KeyboardManager.vcxproj @@ -7,7 +7,7 @@ Win32Proj KeyboardManager true - 10.0.18362.0 + 10.0.19041.0 KeyboardManager diff --git a/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj b/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj index fe8507eb60..45f827c566 100644 --- a/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj +++ b/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj @@ -10,7 +10,7 @@ Win32Proj Wox_Launcher Microsoft.Launcher - 10.0.18362.0 + 10.0.19041.0 diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/AppxManifests/DevelopmentApp/AppxManifest.xml b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/AppxManifests/DevelopmentApp/AppxManifest.xml index f18af9d980..cec2e4d0cf 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/AppxManifests/DevelopmentApp/AppxManifest.xml +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/AppxManifests/DevelopmentApp/AppxManifest.xml @@ -8,7 +8,7 @@ Assets\StoreLogo.png - + diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/AppxManifests/FrameworkApp/AppxManifest.xml b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/AppxManifests/FrameworkApp/AppxManifest.xml index 3d35b6cd2b..da04bb3114 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/AppxManifests/FrameworkApp/AppxManifest.xml +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/AppxManifests/FrameworkApp/AppxManifest.xml @@ -8,7 +8,7 @@ Assets\StoreLogo.png - + diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/AppxManifests/PackagedApp/AppxManifest.xml b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/AppxManifests/PackagedApp/AppxManifest.xml index 19501281f7..61ae22b9c6 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/AppxManifests/PackagedApp/AppxManifest.xml +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/AppxManifests/PackagedApp/AppxManifest.xml @@ -8,7 +8,7 @@ Assets\StoreLogo.png - + diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Microsoft.Plugin.Program.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Microsoft.Plugin.Program.UnitTests.csproj index 13634c1fd4..f8a7c08261 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Microsoft.Plugin.Program.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Microsoft.Plugin.Program.UnitTests.csproj @@ -1,7 +1,7 @@  - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 false AppxManifests\developmentApp\AppxManifest.xml diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj index b635ca2cc7..2f8b373b6c 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj @@ -2,7 +2,7 @@ - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {FDB3555B-58EF-4AE6-B5F1-904719637AB4} Properties Microsoft.Plugin.Program diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests/Microsoft.Plugin.WindowsTerminal.UnitTests.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests/Microsoft.Plugin.WindowsTerminal.UnitTests.csproj index c150e3141d..20676364f8 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests/Microsoft.Plugin.WindowsTerminal.UnitTests.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.UnitTests/Microsoft.Plugin.WindowsTerminal.UnitTests.csproj @@ -1,7 +1,7 @@ - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 true false diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.csproj b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.csproj index 765cff35d2..439c3dc705 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.csproj +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Microsoft.PowerToys.Run.Plugin.WindowsTerminal.csproj @@ -3,7 +3,7 @@ - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 Microsoft.PowerToys.Run.Plugin.WindowsTerminal Microsoft.PowerToys.Run.Plugin.WindowsTerminal $(Version).0 diff --git a/src/modules/launcher/PowerLauncher/PowerLauncher.csproj b/src/modules/launcher/PowerLauncher/PowerLauncher.csproj index ff472f28c4..9127c4e449 100644 --- a/src/modules/launcher/PowerLauncher/PowerLauncher.csproj +++ b/src/modules/launcher/PowerLauncher/PowerLauncher.csproj @@ -3,7 +3,7 @@ PowerToys.Run WinExe - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 true true PowerLauncher.App diff --git a/src/modules/launcher/PowerLauncher/Properties/PublishProfiles/InstallationPublishProfile.pubxml b/src/modules/launcher/PowerLauncher/Properties/PublishProfiles/InstallationPublishProfile.pubxml index 9244003dd4..2d6ffbf5cc 100644 --- a/src/modules/launcher/PowerLauncher/Properties/PublishProfiles/InstallationPublishProfile.pubxml +++ b/src/modules/launcher/PowerLauncher/Properties/PublishProfiles/InstallationPublishProfile.pubxml @@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. FileSystem - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 $(PowerToysRoot)\$(Platform)\$(Configuration)\modules\launcher win-$(Platform) false diff --git a/src/modules/launcher/Wox.Test/Wox.Test.csproj b/src/modules/launcher/Wox.Test/Wox.Test.csproj index b1ae13c949..eaeddda0b6 100644 --- a/src/modules/launcher/Wox.Test/Wox.Test.csproj +++ b/src/modules/launcher/Wox.Test/Wox.Test.csproj @@ -2,7 +2,7 @@ - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {FF742965-9A80-41A5-B042-D6C7D3A21708} Library Properties diff --git a/src/modules/powerrename/PowerRenameContextMenu/AppxManifest.xml b/src/modules/powerrename/PowerRenameContextMenu/AppxManifest.xml new file mode 100644 index 0000000000..efe640dfa8 --- /dev/null +++ b/src/modules/powerrename/PowerRenameContextMenu/AppxManifest.xml @@ -0,0 +1,61 @@ + + + + + PowerRenameContextMenu + Microsoft + Assets\storelogo.png + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/powerrename/PowerRenameContextMenu/Assets/LargeTile.png b/src/modules/powerrename/PowerRenameContextMenu/Assets/LargeTile.png new file mode 100644 index 0000000000000000000000000000000000000000..53ee3777ea27e31b260014cf4074099874ff933a GIT binary patch literal 1755 zcmZvde@q)?7{{+i3tS0qt7{iJ0{^s_^@sZdMMEaBz#P|xjghsxG)6Bvp>vyv%aSq0 z)njao1dV0XNw&c@qmj1e*jgQ$l@_urW5G4RSY#rT1z`#%3;{EB`aJK|TH^lb_3nAT z-_Q4X-(K&IS8UyqsnjYdippfmN-HT!X2MT;Dpcy~-#$k6V z|MR4vU#O&p7TC46pTflb3 zoUJ;ZRf#&8&EwXy5s%!&(q6cN62swD#FH%O-RJsjWPZN3^^@FCIQ&MxXIFo7!I#VI zkpIstuWqUV5uhgs07?k$*!`uiZ=5b#$lI|0c+XJvj(}zSE3MN#EyOK zql(#yA}~Ibl*r(s1}Z^5mmn*-n93g?-ccM+^PN?6HH~h0hjy6@XY*^i<-V)+OZ;p7 z7j`p_sT55xnYsedNIIel^QIIg7i@`2Qi}x5$!tk29$2OQI zs^kQXAKE}5ZJu$)2@Dxn?}}O@f@6@^!%9Tj+o>=jd!^ZuvBE4jb4g}Z5WMBtcmy^~ zoFGVS5|0FA!(1Q%fL?Bj*L+9ZL{mjSO8lzqrQ0UCZ)X zPwk$1HNFgaK%NxGpuXz}#ywXvf2JQ?BQ5uOZM2up4S#ieaxS$!o9o6Z=czNQb} zwAh|xLZ>+WyN%o?^uCAQw&&4o?S$DJ`WP(Hr*grL*qNXlqU0osCQ(Up5F(^$Z5;n&oJIO4uF`k&QL*j{f zU=;#MZ5{@b%qMbjTB3dh-5#mqY>%{0jgS+WdHyG literal 0 HcmV?d00001 diff --git a/src/modules/powerrename/PowerRenameContextMenu/Assets/SmallTile.png b/src/modules/powerrename/PowerRenameContextMenu/Assets/SmallTile.png new file mode 100644 index 0000000000000000000000000000000000000000..f713bba67f551ef91020b75716a4dc8ebd744b1c GIT binary patch literal 637 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 HPwYPdb)5xk literal 0 HcmV?d00001 diff --git a/src/modules/powerrename/PowerRenameContextMenu/Assets/Square150x150Logo.png b/src/modules/powerrename/PowerRenameContextMenu/Assets/Square150x150Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..53ee3777ea27e31b260014cf4074099874ff933a GIT binary patch literal 1755 zcmZvde@q)?7{{+i3tS0qt7{iJ0{^s_^@sZdMMEaBz#P|xjghsxG)6Bvp>vyv%aSq0 z)njao1dV0XNw&c@qmj1e*jgQ$l@_urW5G4RSY#rT1z`#%3;{EB`aJK|TH^lb_3nAT z-_Q4X-(K&IS8UyqsnjYdippfmN-HT!X2MT;Dpcy~-#$k6V z|MR4vU#O&p7TC46pTflb3 zoUJ;ZRf#&8&EwXy5s%!&(q6cN62swD#FH%O-RJsjWPZN3^^@FCIQ&MxXIFo7!I#VI zkpIstuWqUV5uhgs07?k$*!`uiZ=5b#$lI|0c+XJvj(}zSE3MN#EyOK zql(#yA}~Ibl*r(s1}Z^5mmn*-n93g?-ccM+^PN?6HH~h0hjy6@XY*^i<-V)+OZ;p7 z7j`p_sT55xnYsedNIIel^QIIg7i@`2Qi}x5$!tk29$2OQI zs^kQXAKE}5ZJu$)2@Dxn?}}O@f@6@^!%9Tj+o>=jd!^ZuvBE4jb4g}Z5WMBtcmy^~ zoFGVS5|0FA!(1Q%fL?Bj*L+9ZL{mjSO8lzqrQ0UCZ)X zPwk$1HNFgaK%NxGpuXz}#ywXvf2JQ?BQ5uOZM2up4S#ieaxS$!o9o6Z=czNQb} zwAh|xLZ>+WyN%o?^uCAQw&&4o?S$DJ`WP(Hr*grL*qNXlqU0osCQ(Up5F(^$Z5;n&oJIO4uF`k&QL*j{f zU=;#MZ5{@b%qMbjTB3dh-5#mqY>%{0jgS+WdHyG literal 0 HcmV?d00001 diff --git a/src/modules/powerrename/PowerRenameContextMenu/Assets/Square44x44Logo.png b/src/modules/powerrename/PowerRenameContextMenu/Assets/Square44x44Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f713bba67f551ef91020b75716a4dc8ebd744b1c GIT binary patch literal 637 zcmeAS@N?(olHy`uVBq!ia0vp^5g^RL1|$oo8kjIJFu8cTIEGZ*dUI*J;2{SImxtDO zm%3!R$UazoY}x{$j0P5ABYXWr(l=jxJ6ps1W{tV=^>{Dl><3nv3A}sm=EZ)#l3`NR zpZda3^rNox*D1%NC98Z~L*6zipLw~Gxn&(Y-;KmJ+aR6eLabU-L#y8HW%7P-E_-VlLqIabbHPHKT*)fT@9iWJ7iWgOT9%0}Lrj>lztPxWq6sPw3pi z#-<=#$jjrP_DD*i!RLsn0mIA=>4~N)IMYWIf=j%-zuKCdMG%tHYot70D1| zvWa0wMhauW#S>1CnI_;>!1Q3zMA17@DOVq{MQ+{U7^a&yA+%dMCG;WNPV0i;w$tu; zX^b}UKziPM)(<;)ruW;-`)bBN+rQNM*Zs_>?n$|FVFo-e*PZb*@U7VAd+tHb4ec0sq%A~kJcD9FY~qQRMt?ZR3YyDZt}Od;|mgpc{2dv9AHF){kXU%k({ z=Y8JidEayHTkG@twPZ|U3_^%3ct-OgLSiFAqDN!|tbCX@c@?4P`2x*TMK!+Q4b?k0 ziW7!!KF6dPWcF<%I|iznM~`QJ_V7sHGV_D`dhgpA9Vd@&X}ErK+j~_rdv;Bp?OA@a zFXOk7eWOJe5NcK;6h$FaM&7JxNc#-@QTwzW6x#d_zmQNkz5) zPI;kh;3d;5UCJU+9a(cOxX(|edWoOiAEdGU#kPJ&xnc2||3vDbuhBCkj-pb0as$Zl z5;}4n=**n6(1g`JEtSy;SG6X;#-F~Oz3lESG2b5`j@wAwY4Yp<=4Xeb>iH=6aicF?DxD&q{`!&}ct zBI)aycwuobQAf&678Uf+Mmh-@9RUhyH~>?w0dixO0#jZjEc9R^=5NZw=|a(kcB?9^ zfnTiEFXp-q#B;Tn>(O%$A*ud^Rg&eVH6Y_5Y%!E39RR&s?XpG`gKwU!6FE1 z7X)DC7)*(5g}lh`4`{i~DZcWupZI`K)_4P)VE{@gc7@Xsd^86zl~_mOYH?I4!aGeX z^E(_=L6?PgveDQ+r%P@UISEXrkn`LHJZ##+!-anV>6h)IkKp;E@p8+3&(5%kS2)ld*J*rJccZM0iyaAx7+F~GW1UWFK&3X$PE1^}NH zgAG9ck5K!{07OwU@j@Do>TbH=CDEo#4m0cEyAuXy_<&jlzJVcKweSJ5 z&=q~iIn18$w8yb=rmEmHxVEUA^?RwnB?6Qlp1os8@*dWTGL2bhzZ!s*xqScR?EPL` zo(JwNdKUUYy7GtvZ3asXm)cgFvCx9EmAi;|w=a0iGiv%%VYKh`P0Wma4y`Xyx|T~( zAmfGbgbEEC7)j8b@WA@+5W3a61HJXC1dX@6_T|Czk0I0zBk%tnW~()VWITGI!`$c< gARL?UBrYYkwoDw4eo*CrzXGTrZ@;GF>596)00d&n@&Et; literal 0 HcmV?d00001 diff --git a/src/modules/powerrename/PowerRenameContextMenu/Assets/storelogo.png b/src/modules/powerrename/PowerRenameContextMenu/Assets/storelogo.png new file mode 100644 index 0000000000000000000000000000000000000000..a4586f26bdf7841cad10f39cdffe2aca3af252c1 GIT binary patch literal 456 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2o;fF!p=8IEGZ*dUM0H=rDtTTVkd2 z(%lbKn@VS_lUaADVB&;Z6F#LM+mPsa?e>FnHo;HND^!P`-lX%BH~FOg%y&x+t*x!? zg$#_1A1kgsSvO(fw`bOmo;lrJX8byO1j^gf7qohR%mmt z@L)WX;>gqgK|tWJvQ5j;4;=gt4HXVKSMYRv5RhY5vS~TqfK_NAP*r{h!!g^BZ;w4r z7CGdsai)y;fJQc`7{Zc2b==h%o`Op$|bg6a&nL{*m7-=0>k4M4-PXlU;G-?%*(*g>iFt^ U$m#7DfHB12>FVdQ&MBb@0G`#n8vp + + + + 16.0 + Win32Proj + {1dbbb112-4bb1-444b-8ebb-e66555c76ba6} + PowerRenameContextMenu + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + PowerToys.PowerRenameContextMenu + $(SolutionDir)$(Platform)\$(Configuration)\modules\PowerRename\ + + + + Level3 + true + _DEBUG;POWERRENAMECONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + ..\..\..\;..\lib\;..\..\;..\..\..\common\telemetry;%(AdditionalIncludeDirectories) + + + Windows + true + false + runtimeobject.lib;%(AdditionalDependencies) + Source.def + + + del $(OutDir)*.msix /q +MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv + + + + + Level3 + true + true + true + NDEBUG;POWERRENAMECONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + ..\..\..\;..\lib\;..\..\;..\..\..\common\telemetry;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + false + runtimeobject.lib;%(AdditionalDependencies) + Source.def + + + del $(OutDir)*.msix /q +MakeAppx.exe pack /d . /p $(OutDir)PowerRenameContextMenuPackage.msix /nv + + + + + + + + + + + Create + + + + + + + + + + + + + + + + + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} + + + {51920f1f-c28c-4adf-8660-4238766796c2} + + + + + + + + + + + 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}. + + + + + + \ No newline at end of file diff --git a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj.filters b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj.filters new file mode 100644 index 0000000000..2189b10388 --- /dev/null +++ b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameContextMenu.vcxproj.filters @@ -0,0 +1,742 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/src/modules/powerrename/PowerRenameContextMenu/PowerRenameUI.ico b/src/modules/powerrename/PowerRenameContextMenu/PowerRenameUI.ico new file mode 100644 index 0000000000000000000000000000000000000000..4f111feaac04a0afa2cf9b52350541051f1654eb GIT binary patch literal 118203 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace Microsoft::WRL; + +HINSTANCE g_hInst = 0; + +#define BUFSIZE 4096 * 4 + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + g_hInst = hModule; + Trace::RegisterProvider(); + break; + case DLL_PROCESS_DETACH: + Trace::UnregisterProvider(); + break; + } + return TRUE; +} + +class __declspec(uuid("1861E28B-A1F0-4EF4-A1FE-4C8CA88E2174")) PowerRenameContextMenuCommand final : public RuntimeClass, IExplorerCommand, IObjectWithSite> +{ +public: + virtual const wchar_t* Title() { return L"PowerRename"; } + virtual const EXPCMDFLAGS Flags() { return ECF_DEFAULT; } + virtual const EXPCMDSTATE State(_In_opt_ IShellItemArray* selection) { return ECS_ENABLED; } + + // IExplorerCommand + IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name) + { + return SHStrDup(app_name.c_str(), name); + } + + IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* icon) + { + if (!CSettingsInstance().GetShowIconOnMenu()) + { + *icon = nullptr; + return E_NOTIMPL; + } + + std::wstring iconResourcePath = get_module_folderpath(g_hInst); + iconResourcePath += L"\\"; + iconResourcePath += L"PowerRenameUI.ico"; + return SHStrDup(iconResourcePath.c_str(), icon); + } + + IFACEMETHODIMP GetToolTip(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* infoTip) + { + *infoTip = nullptr; + return E_NOTIMPL; + } + + IFACEMETHODIMP GetCanonicalName(_Out_ GUID* guidCommandName) + { + *guidCommandName = __uuidof(this); + return S_OK; + } + + IFACEMETHODIMP GetState(_In_opt_ IShellItemArray* selection, _In_ BOOL okToBeSlow, _Out_ EXPCMDSTATE* cmdState) + { + *cmdState = ECS_ENABLED; + + if (!CSettingsInstance().GetEnabled()) + { + *cmdState = ECS_HIDDEN; + return S_OK; + } + + // Check if we should only be on the extended context menu + if (CSettingsInstance().GetExtendedContextMenuOnly()) + { + *cmdState = ECS_HIDDEN; + return S_OK; + } + + // Check if at least one of the selected items is actually renamable. + if (!ShellItemArrayContainsRenamableItem(selection)) + { + *cmdState = ECS_HIDDEN; + return S_OK; + } + + return S_OK; + } + + IFACEMETHODIMP Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept + try + { + if (selection) + { + RunPowerRename(selection); + } + + return S_OK; + } + CATCH_RETURN(); + + IFACEMETHODIMP GetFlags(_Out_ EXPCMDFLAGS* flags) + { + *flags = Flags(); + return S_OK; + } + IFACEMETHODIMP EnumSubCommands(_COM_Outptr_ IEnumExplorerCommand** enumCommands) + { + *enumCommands = nullptr; + return E_NOTIMPL; + } + + // IObjectWithSite + IFACEMETHODIMP SetSite(_In_ IUnknown* site) noexcept + { + m_site = site; + return S_OK; + } + IFACEMETHODIMP GetSite(_In_ REFIID riid, _COM_Outptr_ void** site) noexcept { return m_site.CopyTo(riid, site); } + +protected: + ComPtr m_site; + +private: + + HRESULT StartNamedPipeServerAndSendData(std::wstring pipe_name) + { + hPipe = CreateNamedPipe( + pipe_name.c_str(), + PIPE_ACCESS_DUPLEX | + WRITE_DAC, + PIPE_TYPE_MESSAGE | + PIPE_READMODE_MESSAGE | + PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, + BUFSIZE, + BUFSIZE, + 0, + NULL); + + if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE) + { + return E_FAIL; + } + + // This call blocks until a client process connects to the pipe + BOOL connected = ConnectNamedPipe(hPipe, NULL); + if (!connected) + { + if (GetLastError() == ERROR_PIPE_CONNECTED) + { + return S_OK; + } + else + { + CloseHandle(hPipe); + } + return E_FAIL; + } + + return S_OK; + } + + HRESULT RunPowerRename(IShellItemArray* psiItemArray) + { + if (CSettingsInstance().GetEnabled()) + { + Trace::Invoked(); + // Set the application path based on the location of the dll + std::wstring path = get_module_folderpath(g_hInst); + path = path + L"\\PowerToys.PowerRename.exe"; + + std::wstring pipe_name(L"\\\\.\\pipe\\powertoys_powerrenameinput_"); + UUID temp_uuid; + wchar_t* uuid_chars = nullptr; + if (UuidCreate(&temp_uuid) == RPC_S_UUID_NO_ADDRESS) + { + auto val = get_last_error_message(GetLastError()); + Logger::warn(L"UuidCreate can not create guid. {}", val.has_value() ? val.value() : L""); + } + else if (UuidToString(&temp_uuid, (RPC_WSTR*)&uuid_chars) != RPC_S_OK) + { + auto val = get_last_error_message(GetLastError()); + Logger::warn(L"UuidToString can not convert to string. {}", val.has_value() ? val.value() : L""); + } + + if (uuid_chars != nullptr) + { + pipe_name += std::wstring(uuid_chars); + RpcStringFree((RPC_WSTR*)&uuid_chars); + uuid_chars = nullptr; + } + create_pipe_thread = std::thread(&PowerRenameContextMenuCommand::StartNamedPipeServerAndSendData, this, pipe_name); + RunNonElevatedEx(path.c_str(), pipe_name, get_module_folderpath(g_hInst)); + create_pipe_thread.join(); + + if (hPipe != INVALID_HANDLE_VALUE) + { + CAtlFile writePipe(hPipe); + + DWORD fileCount = 0; + // Gets the list of files currently selected using the IShellItemArray + psiItemArray->GetCount(&fileCount); + // Iterate over the list of files + for (DWORD i = 0; i < fileCount; i++) + { + IShellItem* shellItem; + psiItemArray->GetItemAt(i, &shellItem); + LPWSTR itemName; + // Retrieves the entire file system path of the file from its shell item + shellItem->GetDisplayName(SIGDN_FILESYSPATH, &itemName); + CString fileName(itemName); + // File name can't contain '?' + fileName.Append(_T("?")); + // Write the file path into the input stream for image resizer + writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR)); + } + writePipe.Close(); + } + } + Trace::InvokedRet(S_OK); + + return S_OK; + } + + + std::thread create_pipe_thread; + HANDLE hPipe = INVALID_HANDLE_VALUE; + std::wstring app_name = L"PowerRename"; +}; + +CoCreatableClass(PowerRenameContextMenuCommand) +CoCreatableClassWrlCreatorMapInclude(PowerRenameContextMenuCommand) + +STDAPI DllGetActivationFactory(_In_ HSTRING activatableClassId, _COM_Outptr_ IActivationFactory** factory) +{ + return Module::GetModule().GetActivationFactory(activatableClassId, factory); +} + +STDAPI DllCanUnloadNow() +{ + return Module::GetModule().GetObjectCount() == 0 ? S_OK : S_FALSE; +} + +STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _COM_Outptr_ void** instance) +{ + return Module::GetModule().GetClassObject(rclsid, riid, instance); +} \ No newline at end of file diff --git a/src/modules/powerrename/PowerRenameContextMenu/framework.h b/src/modules/powerrename/PowerRenameContextMenu/framework.h new file mode 100644 index 0000000000..54b83e94fd --- /dev/null +++ b/src/modules/powerrename/PowerRenameContextMenu/framework.h @@ -0,0 +1,5 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files +#include diff --git a/src/modules/powerrename/PowerRenameContextMenu/packages.config b/src/modules/powerrename/PowerRenameContextMenu/packages.config new file mode 100644 index 0000000000..ed327ca35a --- /dev/null +++ b/src/modules/powerrename/PowerRenameContextMenu/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/modules/powerrename/PowerRenameContextMenu/pch.cpp b/src/modules/powerrename/PowerRenameContextMenu/pch.cpp new file mode 100644 index 0000000000..64b7eef6d6 --- /dev/null +++ b/src/modules/powerrename/PowerRenameContextMenu/pch.cpp @@ -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. diff --git a/src/modules/powerrename/PowerRenameContextMenu/pch.h b/src/modules/powerrename/PowerRenameContextMenu/pch.h new file mode 100644 index 0000000000..885d5d62e4 --- /dev/null +++ b/src/modules/powerrename/PowerRenameContextMenu/pch.h @@ -0,0 +1,13 @@ +// 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 + +// add headers that you want to pre-compile here +#include "framework.h" + +#endif //PCH_H diff --git a/src/modules/powerrename/PowerRenameContextMenu/resource.h b/src/modules/powerrename/PowerRenameContextMenu/resource.h new file mode 100644 index 0000000000..70ea8e555c --- /dev/null +++ b/src/modules/powerrename/PowerRenameContextMenu/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by PowerRenameContextMenu.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 diff --git a/src/modules/powerrename/PowerRenameUILib/App.xaml.cpp b/src/modules/powerrename/PowerRenameUILib/App.xaml.cpp index 38aa58bf21..4cdf8669d0 100644 --- a/src/modules/powerrename/PowerRenameUILib/App.xaml.cpp +++ b/src/modules/powerrename/PowerRenameUILib/App.xaml.cpp @@ -53,15 +53,60 @@ void App::OnLaunched(LaunchActivatedEventArgs const&) { LoggerHelpers::init_logger(moduleName, L"", LogSettings::powerRenameLoggerName); -#define BUFSIZE 4096 * 4 + auto args = std::wstring{ GetCommandLine() }; + size_t pos{ args.rfind(L"\\\\.\\pipe\\") }; + + std::wstring pipe_name; + if (pos != std::wstring::npos) + { + pipe_name = args.substr(pos); + } + + HANDLE hStdin; + + if (pipe_name.size() > 0) + { + while (1) + { + hStdin = CreateFile( + pipe_name.c_str(), // pipe name + GENERIC_READ | GENERIC_WRITE, // read and write + 0, // no sharing + NULL, // default security attributes + OPEN_EXISTING, // opens existing pipe + 0, // default attributes + NULL); // no template file + + // Break if the pipe handle is valid. + if (hStdin != INVALID_HANDLE_VALUE) + break; + + // Exit if an error other than ERROR_PIPE_BUSY occurs. + auto error = GetLastError(); + if (error != ERROR_PIPE_BUSY) + { + break; + } + + if (!WaitNamedPipe(pipe_name.c_str(), 3)) + { + printf("Could not open pipe: 20 second wait timed out."); + } + } + } + else + { + hStdin = GetStdHandle(STD_INPUT_HANDLE); + } - HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); if (hStdin == INVALID_HANDLE_VALUE) { Logger::error(L"Invalid input handle."); ExitProcess(1); } +#define BUFSIZE 4096 * 4 + BOOL bSuccess; WCHAR chBuf[BUFSIZE]; DWORD dwRead; @@ -86,6 +131,7 @@ void App::OnLaunched(LaunchActivatedEventArgs const&) if (!bSuccess) break; } + CloseHandle(hStdin); Logger::debug(L"Starting PowerRename with {} files selected", g_files.size()); diff --git a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj index d760ad982a..97d78f39d4 100644 --- a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj +++ b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj @@ -22,7 +22,7 @@ None Windows Store 10.0 - 10.0.18362.0 + 10.0.19041.0 10.0.17763.0 true true diff --git a/src/modules/powerrename/dll/PowerRenameExt.cpp b/src/modules/powerrename/dll/PowerRenameExt.cpp index 58c73a317c..26d0f22ac2 100644 --- a/src/modules/powerrename/dll/PowerRenameExt.cpp +++ b/src/modules/powerrename/dll/PowerRenameExt.cpp @@ -6,9 +6,10 @@ #include #include "Generated Files/resource.h" -#include -#include #include +#include +#include +#include extern HINSTANCE g_hInst; @@ -63,9 +64,24 @@ HRESULT CPowerRenameMenu::QueryContextMenu(HMENU hMenu, UINT index, UINT uIDFirs if (!CSettingsInstance().GetEnabled()) return E_FAIL; - // Check if we should only be on the extended context menu - if (CSettingsInstance().GetExtendedContextMenuOnly() && (!(uFlags & CMF_EXTENDEDVERBS))) - return E_FAIL; + // Win11 context menu can't distinguish between extended and default menu, so use this one + if (package::IsWin11OrGreater()) + { + if (CSettingsInstance().GetExtendedContextMenuOnly() && (uFlags & CMF_EXTENDEDVERBS)) + { + // continue + } + else + { + return E_FAIL; + } + } + else + { + // Check if we should only be on the extended context menu + if (CSettingsInstance().GetExtendedContextMenuOnly() && (!(uFlags & CMF_EXTENDEDVERBS))) + return E_FAIL; + } // Check if at least one of the selected items is actually renamable. if (!DataObjectContainsRenamableItem(m_spdo)) diff --git a/src/modules/powerrename/dll/PowerRenameExt.vcxproj b/src/modules/powerrename/dll/PowerRenameExt.vcxproj index 83b3ce76c3..ebdb4c373a 100644 --- a/src/modules/powerrename/dll/PowerRenameExt.vcxproj +++ b/src/modules/powerrename/dll/PowerRenameExt.vcxproj @@ -8,7 +8,7 @@ 15.0 {B25AC7A5-FB9F-4789-B392-D5C85E948670} PowerRenameExt - 10.0.18362.0 + 10.0.19041.0 @@ -64,6 +64,9 @@ {98537082-0fdb-40de-abd8-0dc5a4269bab} + + {cc6e41ac-8174-4e8a-8d22-85dd7f4851df} + {51920f1f-c28c-4adf-8660-4238766796c2} diff --git a/src/modules/powerrename/dll/dllmain.cpp b/src/modules/powerrename/dll/dllmain.cpp index d615703924..4b01877df7 100644 --- a/src/modules/powerrename/dll/dllmain.cpp +++ b/src/modules/powerrename/dll/dllmain.cpp @@ -1,15 +1,22 @@ #include "pch.h" + +#include "Generated Files/resource.h" +#include "PowerRenameConstants.h" #include "PowerRenameExt.h" + #include #include #include +#include + #include #include #include +#include +#include #include -#include "Generated Files/resource.h" + #include -#include std::atomic g_dwModuleRefCount = 0; HINSTANCE g_hInst = 0; @@ -161,6 +168,8 @@ private: std::wstring app_key; public: + + // Return the localized display name of the powertoy virtual PCWSTR get_name() override { @@ -178,6 +187,19 @@ public: { Logger::info(L"PowerRename enabled"); m_enabled = true; + + if (package::IsWin11OrGreater()) + { + std::wstring path = get_module_folderpath(g_hInst); + std::wstring packageUri = path + L"\\PowerRenameContextMenuPackage.msix"; + + std::wstring packageDisplayName{ L"PowerRenameContextMenu" }; + if (!package::IsPackageRegistered(packageDisplayName)) + { + package::RegisterSparsePackage(path, packageUri); + } + } + save_settings(); } diff --git a/src/modules/powerrename/lib/Helpers.cpp b/src/modules/powerrename/lib/Helpers.cpp index 45ab3e4715..f0476dd1dd 100644 --- a/src/modules/powerrename/lib/Helpers.cpp +++ b/src/modules/powerrename/lib/Helpers.cpp @@ -520,6 +520,31 @@ BOOL GetEnumeratedFileName(__out_ecount(cchMax) PWSTR pszUniqueName, UINT cchMax return fRet; } +// Iterate through the shell items array and checks if at least 1 item has SFGAO_CANRENAME. +// We do not enumerate child items - only the items the user selected. +bool ShellItemArrayContainsRenamableItem(_In_ IShellItemArray* shellItemArray) +{ + bool hasRenamable = false; + IEnumShellItems* spesi; + if (SUCCEEDED(shellItemArray->EnumItems(&spesi))) + { + ULONG celtFetched; + IShellItem* spsi; + while ((S_OK == spesi->Next(1, &spsi, &celtFetched))) + { + SFGAOF attrs; + if (SUCCEEDED(spsi->GetAttributes(SFGAO_CANRENAME, &attrs)) && + attrs & SFGAO_CANRENAME) + { + hasRenamable = true; + break; + } + } + } + + return hasRenamable; +} + // Iterate through the data source and checks if at least 1 item has SFGAO_CANRENAME. // We do not enumerate child items - only the items the user selected. bool DataObjectContainsRenamableItem(_In_ IUnknown* dataSource) diff --git a/src/modules/powerrename/lib/Helpers.h b/src/modules/powerrename/lib/Helpers.h index 68a5264e08..dbe21ceef3 100644 --- a/src/modules/powerrename/lib/Helpers.h +++ b/src/modules/powerrename/lib/Helpers.h @@ -8,6 +8,7 @@ HRESULT GetTrimmedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source); HRESULT GetTransformedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, DWORD flags, bool isFolder); HRESULT GetDatedFileName(_Out_ PWSTR result, UINT cchMax, _In_ PCWSTR source, SYSTEMTIME fileTime); bool isFileTimeUsed(_In_ PCWSTR source); +bool ShellItemArrayContainsRenamableItem(_In_ IShellItemArray* shellItemArray); bool DataObjectContainsRenamableItem(_In_ IUnknown* dataSource); HRESULT GetShellItemArrayFromDataObject(_In_ IUnknown* dataSource, _COM_Outptr_ IShellItemArray** items); BOOL GetEnumeratedFileName( diff --git a/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandler.csproj b/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandler.csproj index 1aecc28247..5beba910f4 100644 --- a/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandler.csproj +++ b/src/modules/previewpane/GcodePreviewHandler/GcodePreviewHandler.csproj @@ -16,7 +16,7 @@ {805306FF-A562-4415-8DEF-E493BDC45918} Microsoft.PowerToys.PreviewHandler.Gcode - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 true $(SolutionDir)$(Platform)\$(Configuration)\obj\$(AssemblyName)\ diff --git a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj index a13c760546..29692dd89d 100644 --- a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj +++ b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.csproj @@ -11,7 +11,7 @@ true true win10-x64;win10-arm64 - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 diff --git a/src/modules/previewpane/MarkdownPreviewHandler/Properties/PublishProfiles/InstallationPublishProfile.pubxml b/src/modules/previewpane/MarkdownPreviewHandler/Properties/PublishProfiles/InstallationPublishProfile.pubxml index 9833d386ca..3cecd08b49 100644 --- a/src/modules/previewpane/MarkdownPreviewHandler/Properties/PublishProfiles/InstallationPublishProfile.pubxml +++ b/src/modules/previewpane/MarkdownPreviewHandler/Properties/PublishProfiles/InstallationPublishProfile.pubxml @@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. FileSystem - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 $(PowerToysRoot)\$(Platform)\$(Configuration)\modules\FileExplorerPreview win10-$(Platform) false diff --git a/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj b/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj index 6951ecc59c..61e1f37c4d 100644 --- a/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj +++ b/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandler.csproj @@ -15,7 +15,7 @@ Microsoft.PowerToys.PreviewHandler.Monaco - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 true $(SolutionDir)$(Platform)\$(Configuration)\obj\$(AssemblyName)\ PowerToys.MonacoPreviewHandler diff --git a/src/modules/previewpane/MonacoPreviewHandler/Properties/PublishProfiles/InstallationPublishProfile.pubxml b/src/modules/previewpane/MonacoPreviewHandler/Properties/PublishProfiles/InstallationPublishProfile.pubxml index 9833d386ca..3cecd08b49 100644 --- a/src/modules/previewpane/MonacoPreviewHandler/Properties/PublishProfiles/InstallationPublishProfile.pubxml +++ b/src/modules/previewpane/MonacoPreviewHandler/Properties/PublishProfiles/InstallationPublishProfile.pubxml @@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. FileSystem - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 $(PowerToysRoot)\$(Platform)\$(Configuration)\modules\FileExplorerPreview win10-$(Platform) false diff --git a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj index 21ab18e923..509df95214 100644 --- a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj +++ b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj @@ -15,7 +15,7 @@ {69E1EE8D-143A-4060-9129-4658ACF14AAF} Microsoft.PowerToys.PreviewHandler.Pdf - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 true $(SolutionDir)$(Platform)\$(Configuration)\obj\$(AssemblyName)\ PowerToys.PdfPreviewHandler diff --git a/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj b/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj index 16717a7f1c..0178795f14 100644 --- a/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj +++ b/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj @@ -6,7 +6,7 @@ PowerToys.PdfThumbnailProvider PowerToys.PdfThumbnailProvider PowerToys PdfPreviewHandler - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 true true PowerToys PdfPreviewHandler diff --git a/src/modules/previewpane/SvgPreviewHandler/Properties/PublishProfiles/InstallationPublishProfile.pubxml b/src/modules/previewpane/SvgPreviewHandler/Properties/PublishProfiles/InstallationPublishProfile.pubxml index 9833d386ca..3cecd08b49 100644 --- a/src/modules/previewpane/SvgPreviewHandler/Properties/PublishProfiles/InstallationPublishProfile.pubxml +++ b/src/modules/previewpane/SvgPreviewHandler/Properties/PublishProfiles/InstallationPublishProfile.pubxml @@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. FileSystem - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 $(PowerToysRoot)\$(Platform)\$(Configuration)\modules\FileExplorerPreview win10-$(Platform) false diff --git a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj index 5d08472f65..be5c7a2237 100644 --- a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj +++ b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.csproj @@ -11,7 +11,7 @@ true true win10-x64;win10-arm64 - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 diff --git a/src/modules/previewpane/SvgThumbnailProvider/Properties/PublishProfiles/InstallationPublishProfile.pubxml b/src/modules/previewpane/SvgThumbnailProvider/Properties/PublishProfiles/InstallationPublishProfile.pubxml index 9833d386ca..3cecd08b49 100644 --- a/src/modules/previewpane/SvgThumbnailProvider/Properties/PublishProfiles/InstallationPublishProfile.pubxml +++ b/src/modules/previewpane/SvgThumbnailProvider/Properties/PublishProfiles/InstallationPublishProfile.pubxml @@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. FileSystem - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 $(PowerToysRoot)\$(Platform)\$(Configuration)\modules\FileExplorerPreview win10-$(Platform) false diff --git a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj index d06077c391..5d57ae7b8c 100644 --- a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj +++ b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.csproj @@ -6,7 +6,7 @@ PowerToys.SvgThumbnailProvider PowerToys.SvgThumbnailProvider PowerToys SvgPreviewHandler - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 true true PowerToys SvgPreviewHandler diff --git a/src/modules/previewpane/UnitTests-GcodePreviewHandler/UnitTests-GcodePreviewHandler.csproj b/src/modules/previewpane/UnitTests-GcodePreviewHandler/UnitTests-GcodePreviewHandler.csproj index 1d0fbdd0af..5960dc1933 100644 --- a/src/modules/previewpane/UnitTests-GcodePreviewHandler/UnitTests-GcodePreviewHandler.csproj +++ b/src/modules/previewpane/UnitTests-GcodePreviewHandler/UnitTests-GcodePreviewHandler.csproj @@ -9,7 +9,7 @@ {FCF3E52D-B80A-4FC3-98FD-6391354F0EE3} PdfPreviewHandlerUnitTests - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages diff --git a/src/modules/previewpane/UnitTests-GcodeThumbnailProvider/UnitTests-GcodeThumbnailProvider.csproj b/src/modules/previewpane/UnitTests-GcodeThumbnailProvider/UnitTests-GcodeThumbnailProvider.csproj index 98eb421a3b..c85ad844d6 100644 --- a/src/modules/previewpane/UnitTests-GcodeThumbnailProvider/UnitTests-GcodeThumbnailProvider.csproj +++ b/src/modules/previewpane/UnitTests-GcodeThumbnailProvider/UnitTests-GcodeThumbnailProvider.csproj @@ -9,7 +9,7 @@ {133281D8-1BCE-4D07-B31E-796612A9609E} GcodeThumbnailProviderUnitTests - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages diff --git a/src/modules/previewpane/UnitTests-MarkdownPreviewHandler/UnitTests-MarkdownPreviewHandler.csproj b/src/modules/previewpane/UnitTests-MarkdownPreviewHandler/UnitTests-MarkdownPreviewHandler.csproj index 7e699fb780..6f12104e43 100644 --- a/src/modules/previewpane/UnitTests-MarkdownPreviewHandler/UnitTests-MarkdownPreviewHandler.csproj +++ b/src/modules/previewpane/UnitTests-MarkdownPreviewHandler/UnitTests-MarkdownPreviewHandler.csproj @@ -10,7 +10,7 @@ {A2B51B8B-8F90-424E-BC97-F9AB7D76CA1A} PreviewPaneUnitTests PreviewPaneUnitTests - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages diff --git a/src/modules/previewpane/UnitTests-PdfPreviewHandler/UnitTests-PdfPreviewHandler.csproj b/src/modules/previewpane/UnitTests-PdfPreviewHandler/UnitTests-PdfPreviewHandler.csproj index 49890db593..ba69033755 100644 --- a/src/modules/previewpane/UnitTests-PdfPreviewHandler/UnitTests-PdfPreviewHandler.csproj +++ b/src/modules/previewpane/UnitTests-PdfPreviewHandler/UnitTests-PdfPreviewHandler.csproj @@ -9,7 +9,7 @@ {ECC20689-002A-4354-95A6-B58DF089C6FF} PdfPreviewHandlerUnitTests - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages diff --git a/src/modules/previewpane/UnitTests-PdfThumbnailProvider/UnitTests-PdfThumbnailProvider.csproj b/src/modules/previewpane/UnitTests-PdfThumbnailProvider/UnitTests-PdfThumbnailProvider.csproj index c74d86d7b9..c012c533b2 100644 --- a/src/modules/previewpane/UnitTests-PdfThumbnailProvider/UnitTests-PdfThumbnailProvider.csproj +++ b/src/modules/previewpane/UnitTests-PdfThumbnailProvider/UnitTests-PdfThumbnailProvider.csproj @@ -9,7 +9,7 @@ {F40C3397-1834-4530-B2D9-8F8B8456BCDF} PdfThumbnailProviderUnitTests - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages diff --git a/src/modules/previewpane/UnitTests-StlThumbnailProvider/UnitTests-StlThumbnailProvider.csproj b/src/modules/previewpane/UnitTests-StlThumbnailProvider/UnitTests-StlThumbnailProvider.csproj index 09d598e6cb..15c74e96e3 100644 --- a/src/modules/previewpane/UnitTests-StlThumbnailProvider/UnitTests-StlThumbnailProvider.csproj +++ b/src/modules/previewpane/UnitTests-StlThumbnailProvider/UnitTests-StlThumbnailProvider.csproj @@ -9,7 +9,7 @@ {F1F6B6B6-9F18-4A17-8B5C-97DF552C53DC} StlThumbnailProviderUnitTests - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages diff --git a/src/modules/previewpane/UnitTests-SvgPreviewHandler/UnitTests-SvgPreviewHandler.csproj b/src/modules/previewpane/UnitTests-SvgPreviewHandler/UnitTests-SvgPreviewHandler.csproj index e1afd46bbc..e0edff0a48 100644 --- a/src/modules/previewpane/UnitTests-SvgPreviewHandler/UnitTests-SvgPreviewHandler.csproj +++ b/src/modules/previewpane/UnitTests-SvgPreviewHandler/UnitTests-SvgPreviewHandler.csproj @@ -9,7 +9,7 @@ {060D75DA-2D1C-48E6-A4A1-6F0718B64661} SvgPreviewHandlerUnitTests - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages diff --git a/src/modules/previewpane/UnitTests-SvgThumbnailProvider/UnitTests-SvgThumbnailProvider.csproj b/src/modules/previewpane/UnitTests-SvgThumbnailProvider/UnitTests-SvgThumbnailProvider.csproj index 1b3cb3c373..1390c1c0ba 100644 --- a/src/modules/previewpane/UnitTests-SvgThumbnailProvider/UnitTests-SvgThumbnailProvider.csproj +++ b/src/modules/previewpane/UnitTests-SvgThumbnailProvider/UnitTests-SvgThumbnailProvider.csproj @@ -9,7 +9,7 @@ {1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E} SvgThumbnailProviderUnitTests - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages diff --git a/src/modules/videoconference/VideoConferenceModule/VideoConference.vcxproj b/src/modules/videoconference/VideoConferenceModule/VideoConference.vcxproj index 9bae4d7a74..4215193483 100644 --- a/src/modules/videoconference/VideoConferenceModule/VideoConference.vcxproj +++ b/src/modules/videoconference/VideoConferenceModule/VideoConference.vcxproj @@ -6,7 +6,7 @@ {5ABA70DE-3A3F-41F6-A1F5-D1F74F54F9BB} Win32Proj overlaywindow - 10.0.18362.0 + 10.0.19041.0 VideoConferenceModule diff --git a/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.vcxproj b/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.vcxproj index 2222dfe4dd..be60fac0f5 100644 --- a/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.vcxproj +++ b/src/modules/videoconference/VideoConferenceProxyFilter/VideoConferenceProxyFilter.vcxproj @@ -33,7 +33,7 @@ VideoConferenceProxyFilter VideoConferenceProxyFilter true - 10.0.18362.0 + 10.0.19041.0 diff --git a/src/modules/videoconference/VideoConferenceShared/VideoConferenceShared.vcxproj b/src/modules/videoconference/VideoConferenceShared/VideoConferenceShared.vcxproj index 8820e447c3..ade59c8e5f 100644 --- a/src/modules/videoconference/VideoConferenceShared/VideoConferenceShared.vcxproj +++ b/src/modules/videoconference/VideoConferenceShared/VideoConferenceShared.vcxproj @@ -38,7 +38,7 @@ {459e0768-7ebd-4c41-bba1-6db3b3815e0a} VideoConferenceShared true - 10.0.18362.0 + 10.0.19041.0 diff --git a/src/runner/PowerToys.exe.manifest b/src/runner/PowerToys.exe.manifest index 65f881cabc..fd0fa537c0 100644 --- a/src/runner/PowerToys.exe.manifest +++ b/src/runner/PowerToys.exe.manifest @@ -3,7 +3,7 @@ - + \ No newline at end of file diff --git a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj index ad228e6ef3..1aac902138 100644 --- a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj +++ b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj @@ -2,7 +2,7 @@ WinExe - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 10.0.17763.0 Microsoft.PowerToys.Settings.UI app.manifest diff --git a/src/settings-ui/Settings.UI/Properties/PublishProfiles/InstallationPublishProfile.pubxml b/src/settings-ui/Settings.UI/Properties/PublishProfiles/InstallationPublishProfile.pubxml index 2ae59c976c..a889615b38 100644 --- a/src/settings-ui/Settings.UI/Properties/PublishProfiles/InstallationPublishProfile.pubxml +++ b/src/settings-ui/Settings.UI/Properties/PublishProfiles/InstallationPublishProfile.pubxml @@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. FileSystem - net6.0-windows10.0.18362.0 + net6.0-windows10.0.19041.0 $(PowerToysRoot)\$(Platform)\$(Configuration)\Settings win10-$(Platform) false diff --git a/tools/BugReportTool/BugReportTool/BugReportTool.vcxproj b/tools/BugReportTool/BugReportTool/BugReportTool.vcxproj index a41eb84529..e31770bea8 100644 --- a/tools/BugReportTool/BugReportTool/BugReportTool.vcxproj +++ b/tools/BugReportTool/BugReportTool/BugReportTool.vcxproj @@ -48,6 +48,7 @@ + @@ -68,6 +69,7 @@ + diff --git a/tools/BugReportTool/BugReportTool/BugReportTool.vcxproj.filters b/tools/BugReportTool/BugReportTool/BugReportTool.vcxproj.filters index d574367de9..5e981b3361 100644 --- a/tools/BugReportTool/BugReportTool/BugReportTool.vcxproj.filters +++ b/tools/BugReportTool/BugReportTool/BugReportTool.vcxproj.filters @@ -15,6 +15,7 @@ + @@ -33,5 +34,6 @@ + \ No newline at end of file diff --git a/tools/BugReportTool/BugReportTool/Main.cpp b/tools/BugReportTool/BugReportTool/Main.cpp index 5bc9b5d603..f36da41be5 100644 --- a/tools/BugReportTool/BugReportTool/Main.cpp +++ b/tools/BugReportTool/BugReportTool/Main.cpp @@ -14,6 +14,7 @@ #include #include +#include "Package.h" #include "ReportMonitorInfo.h" #include "RegistryUtils.h" #include "EventViewer.h" @@ -351,6 +352,8 @@ int wmain(int argc, wchar_t* argv[], wchar_t*) ReportInstallerLogs(tempDir, reportDir); + ReportInstalledContextMenuPackages(reportDir); + // Zip folder auto zipPath = path::path(saveZipPath); diff --git a/tools/BugReportTool/BugReportTool/Package.cpp b/tools/BugReportTool/BugReportTool/Package.cpp new file mode 100644 index 0000000000..66d3ead465 --- /dev/null +++ b/tools/BugReportTool/BugReportTool/Package.cpp @@ -0,0 +1,78 @@ +#include "Package.h" + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +std::optional GetPackage(std::wstring packageDisplayName) +{ + using namespace winrt::Windows::Foundation; + using namespace winrt::Windows::Management::Deployment; + + PackageManager packageManager; + + for (auto const& package : packageManager.FindPackagesForUser({})) + { + const auto& packageFullName = std::wstring{ package.Id().FullName() }; + + if (packageFullName.contains(packageDisplayName)) + { + return { package }; + } + } + + return std::nullopt; +} + +std::wstringstream GetPackageInfo(winrt::Windows::ApplicationModel::Package package) { + std::wstringstream packageInfo; + packageInfo << L"Display name: " << std::wstring(package.DisplayName()) << std::endl; + packageInfo << L"Full name: " << std::wstring(package.Id().FullName()) << std::endl; + packageInfo << L"Version: " << package.Id().Version().Major << L"." + << package.Id().Version().Minor << L"." + << package.Id().Version().Build << L"." + << package.Id().Version().Revision << L"." << std::endl; + packageInfo << L"Publisher: " << std::wstring(package.Id().Publisher()) << std::endl; + packageInfo << L"Status: " << (package.Status().VerifyIsOK() ? std::wstring(L"OK") : std::wstring(L"Not OK")) << std::endl; + + return packageInfo; +} + +void ReportInstalledContextMenuPackages(const std::filesystem::path& reportDir) +{ + const wchar_t* ImageResizerContextMenuPackageDisplayName = L"ImageResizerContextMenu"; + const wchar_t* PowerRenameContextMenuPackageDisplayName = L"PowerRenameContextMenu"; + + auto reportPath = reportDir; + reportPath.append("context-menu-packages.txt"); + + std::wofstream packagesReport(reportPath); + + try + { + auto imageResizerPackage = GetPackage(ImageResizerContextMenuPackageDisplayName); + if (imageResizerPackage) + { + packagesReport << GetPackageInfo(*imageResizerPackage).str() << std::endl; + } + + auto powerRenamePackage = GetPackage(PowerRenameContextMenuPackageDisplayName); + if (powerRenamePackage) + { + packagesReport << GetPackageInfo(*powerRenamePackage).str() << std::endl; + } + } + catch (...) + { + printf("Failed to report installed context menu packages"); + } +} diff --git a/tools/BugReportTool/BugReportTool/Package.h b/tools/BugReportTool/BugReportTool/Package.h new file mode 100644 index 0000000000..a7527793d6 --- /dev/null +++ b/tools/BugReportTool/BugReportTool/Package.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include + +std::optional GetPackage(std::wstring packageDisplayName); +std::wstringstream GetPackageInfo(winrt::Windows::ApplicationModel::Package package); +void ReportInstalledContextMenuPackages(const std::filesystem::path& reportDir); diff --git a/tools/MonitorReportTool/MonitorReportTool.vcxproj b/tools/MonitorReportTool/MonitorReportTool.vcxproj index ec20ed5c06..bcd7b8874e 100644 --- a/tools/MonitorReportTool/MonitorReportTool.vcxproj +++ b/tools/MonitorReportTool/MonitorReportTool.vcxproj @@ -5,7 +5,7 @@ Win32Proj {0febafaf-cb77-41f0-8ef9-8e3ad4b4f842} MonitorReportTool - 10.0.18362.0 + 10.0.19041.0 diff --git a/tools/StylesReportTool/StylesReportTool.vcxproj b/tools/StylesReportTool/StylesReportTool.vcxproj index 5acb15465d..6e3ee0449d 100644 --- a/tools/StylesReportTool/StylesReportTool.vcxproj +++ b/tools/StylesReportTool/StylesReportTool.vcxproj @@ -5,7 +5,7 @@ Win32Proj {0febafaf-cb77-41f0-8ef9-8e3ad4b4f842} StylesReportTool - 10.0.18362.0 + 10.0.19041.0 diff --git a/tools/build/convert-resx-to-rc.ps1 b/tools/build/convert-resx-to-rc.ps1 index 3884c4eafa..1356aeb20c 100644 --- a/tools/build/convert-resx-to-rc.ps1 +++ b/tools/build/convert-resx-to-rc.ps1 @@ -141,15 +141,17 @@ Foreach-Object { exit 0 } - # Add string table syntax - $newLinesForRCFile = "`r`nSTRINGTABLE`r`nBEGIN" + $newLinesForRCFile + "`r`nEND" + if ($newLinesForRCFile -ne "") { + # Add string table syntax + $newLinesForRCFile = "`r`nSTRINGTABLE`r`nBEGIN" + $newLinesForRCFile + "`r`nEND" - $langStart = "`r`n/////////////////////////////////////////////////////////////////////////////`r`n// " + $langData[3] + " resources`r`n`r`n" - $langStart += "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_" + $langData[0] + ")`r`nLANGUAGE LANG_" + $langData[1] + ", SUBLANG_" + $langData[2] + "`r`n" + $langStart = "`r`n/////////////////////////////////////////////////////////////////////////////`r`n// " + $langData[3] + " resources`r`n`r`n" + $langStart += "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_" + $langData[0] + ")`r`nLANGUAGE LANG_" + $langData[1] + ", SUBLANG_" + $langData[2] + "`r`n" - $langEnd = "`r`n`r`n#endif // " + $langData[3] + " resources`r`n/////////////////////////////////////////////////////////////////////////////`r`n" + $langEnd = "`r`n`r`n#endif // " + $langData[3] + " resources`r`n/////////////////////////////////////////////////////////////////////////////`r`n" - $newLinesForRCFile = $langStart + $newLinesForRCFile + $langEnd + $newLinesForRCFile = $langStart + $newLinesForRCFile + $langEnd + } # Initialize the rc file with an auto-generation warning and content from the base rc if (!$rcFileUpdated) { diff --git a/tools/project_template/ModuleTemplate/ModuleTemplateCompileTest.vcxproj b/tools/project_template/ModuleTemplate/ModuleTemplateCompileTest.vcxproj index a43fc91e9e..4761c8466e 100644 --- a/tools/project_template/ModuleTemplate/ModuleTemplateCompileTest.vcxproj +++ b/tools/project_template/ModuleTemplate/ModuleTemplateCompileTest.vcxproj @@ -6,7 +6,7 @@ {64A80062-4D8B-4229-8A38-DFA1D7497749} Win32Proj templatenamespace - 10.0.18362.0 + 10.0.19041.0 ModuleTemplateCompileTest