From 4737ec987ef9b6ecc391a9582b8a5a78c364bf56 Mon Sep 17 00:00:00 2001 From: Alexandre Zollinger Chohfi Date: Wed, 18 Jun 2025 01:34:26 -0700 Subject: [PATCH] Added basic support for Windows App Actions. (#39927) ## Summary of the Pull Request Adds basic support for finding, listing, and executing Windows App Actions on files found by the Microsoft.CmdPal.Ext.Indexer extension. ## PR Checklist - [X] **Closes:** #39926 - [X] **Communication:** I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [X] **Localization:** All end user facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments We also update cswin32 to stable version. ## Validation Steps Performed Validated that it doesn't show on older versions of Windows (<26100 insiders) and that it does work on newer version that have the App Actions runtime. --------- Co-authored-by: Gordon Lam (SH) Co-authored-by: Mike Griese Co-authored-by: Leilei Zhang --- .github/actions/spell-check/expect.txt | 2 + .pipelines/v2/templates/job-build-project.yml | 3 +- .vsconfig | 1 + Cpp.Build.props | 4 +- Directory.Packages.props | 4 +- NOTICE.md | 4 +- installer/PowerToysSetup/publish.cmd | 8 +- src/Common.Dotnet.CsWinRT.props | 4 +- .../CropAndLock/CropAndLock.vcxproj | 2 +- .../InstallationPublishProfile.pubxml | 2 +- .../PowerToys.MeasureToolCore.vcxproj | 8 +- .../MeasureToolCore/packages.config | 2 +- .../NewPlus.ShellExtension.win10.vcxproj | 2 +- .../Directory.Packages.props | 4 +- .../TemplateCmdPalExtension.csproj | 4 +- .../Microsoft.CmdPal.UI/MainWindow.xaml.cs | 6 +- .../Microsoft.Terminal.UI.vcxproj | 2 +- .../Programs/UWPApplication.cs | 5 +- .../Actions/ActionRuntimeFactory.cs | 42 ++++++++ .../Assets/Actions.png | Bin 0 -> 4408 bytes .../Commands/ExecuteActionCommand.cs | 43 ++++++++ .../Data/IndexerListItem.cs | 22 ++++- .../Microsoft.CmdPal.Ext.Indexer.csproj | 3 + .../Native/NativeHelpers.cs | 1 + .../NativeMethods.json | 5 +- .../Pages/ActionsListContextItem.cs | 93 ++++++++++++++++++ .../Pages/Icons.cs | 2 + .../Properties/Resources.Designer.cs | 9 ++ .../Properties/Resources.resx | 3 + .../Helpers/DefaultBrowserInfo.cs | 18 ++-- .../Utilities.cs | 2 +- ...icrosoft.CommandPalette.Extensions.vcxproj | 4 +- .../packages.config | 2 +- .../ShellPreviewHandlerControl.xaml.cs | 35 ++++--- .../Peek.FilePreviewer/NativeMethods.json | 5 +- .../Helpers/IStreamWrapper.cs | 8 +- .../ShellPreviewHandlerPreviewer.cs | 4 +- .../peek/Peek.UI/Extensions/HWNDExtensions.cs | 8 +- .../Peek.UI/Extensions/WindowExtensions.cs | 14 +-- .../Peek.UI/Helpers/FileExplorerHelper.cs | 6 +- src/modules/peek/Peek.UI/NativeMethods.json | 5 + src/modules/peek/Peek.UI/PeekXAML/App.xaml.cs | 2 +- .../peek/Peek.UI/PeekXAML/MainWindow.xaml.cs | 2 +- .../PowerRename.FuzzingTest.vcxproj | 2 +- .../PowerRenameUILib/PowerRenameUI.vcxproj | 8 +- .../PowerRenameUILib/packages.config | 2 +- 46 files changed, 324 insertions(+), 93 deletions(-) create mode 100644 src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Actions/ActionRuntimeFactory.cs create mode 100644 src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Assets/Actions.png create mode 100644 src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Commands/ExecuteActionCommand.cs create mode 100644 src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Pages/ActionsListContextItem.cs create mode 100644 src/modules/peek/Peek.UI/NativeMethods.json diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 7355d90790..63ad5e7ee0 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -204,6 +204,7 @@ CLIPSIBLINGS closesocket clp CLSCTX +CLSCTXLOCALSERVER clsids Clusion cmder @@ -826,6 +827,7 @@ LOCALDISPLAY localpackage LOCALSYSTEM LOCATIONCHANGE +LOCKTYPE LOGFONT LOGFONTW logon diff --git a/.pipelines/v2/templates/job-build-project.yml b/.pipelines/v2/templates/job-build-project.yml index c642402623..8d7afc8900 100644 --- a/.pipelines/v2/templates/job-build-project.yml +++ b/.pipelines/v2/templates/job-build-project.yml @@ -102,7 +102,7 @@ jobs: ${{ else }}: OutputBuildPlatform: ${{ platform }} variables: - MakeAppxPath: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\MakeAppx.exe' + MakeAppxPath: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x86\MakeAppx.exe' # Azure DevOps abhors a vacuum # If these are blank, expansion will fail later on... which will result in direct substitution of the variable *names* # later on. We'll just... set them to a single space and if we need to, check IsNullOrWhiteSpace. @@ -335,6 +335,7 @@ jobs: /p:VCRTForwarders-IncludeDebugCRT=false /p:PowerToysRoot=$(Build.SourcesDirectory) /p:PublishProfile=InstallationPublishProfile.pubxml + /p:TargetFramework=net9.0-windows10.0.26100.0 /bl:$(LogOutputDirectory)\publish-${{ join('_',split(project, '/')) }}.binlog $(RestoreAdditionalProjectSourcesArg) platform: $(BuildPlatform) diff --git a/.vsconfig b/.vsconfig index 77ec8b0ffd..90abacd81c 100644 --- a/.vsconfig +++ b/.vsconfig @@ -9,6 +9,7 @@ "Microsoft.VisualStudio.Component.Windows10SDK.19041", "Microsoft.VisualStudio.Component.Windows10SDK.20348", "Microsoft.VisualStudio.Component.Windows10SDK.22621", + "Microsoft.VisualStudio.Component.Windows10SDK.26100", "Microsoft.VisualStudio.ComponentGroup.UWP.VC", "Microsoft.VisualStudio.Component.UWP.VC.ARM64", "Microsoft.VisualStudio.Component.VC.Runtimes.ARM64.Spectre", diff --git a/Cpp.Build.props b/Cpp.Build.props index 06c22b45bf..5a4538f940 100644 --- a/Cpp.Build.props +++ b/Cpp.Build.props @@ -96,8 +96,8 @@ - 10.0.22621.0 - 10.0.22621.0 + 10.0.26100.0 + 10.0.26100.0 10.0.19041.0 diff --git a/Directory.Packages.props b/Directory.Packages.props index 06f8e8ddef..8651672751 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -47,14 +47,14 @@ - + - + diff --git a/NOTICE.md b/NOTICE.md index f36311d4ea..60b480d6c0 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -1533,9 +1533,9 @@ SOFTWARE. - Microsoft.Web.WebView2 1.0.2903.40 - Microsoft.Win32.SystemEvents 9.0.6 - Microsoft.Windows.Compatibility 9.0.6 -- Microsoft.Windows.CsWin32 0.2.46-beta +- Microsoft.Windows.CsWin32 0.3.183 - Microsoft.Windows.CsWinRT 2.2.0 -- Microsoft.Windows.SDK.BuildTools 10.0.22621.2428 +- Microsoft.Windows.SDK.BuildTools 10.0.26100.4188 - Microsoft.WindowsAppSDK 1.7.250513003 - Microsoft.WindowsPackageManager.ComInterop 1.10.340 - Microsoft.Xaml.Behaviors.WinUI.Managed 2.0.9 diff --git a/installer/PowerToysSetup/publish.cmd b/installer/PowerToysSetup/publish.cmd index 18fa40b4aa..c6113bf285 100644 --- a/installer/PowerToysSetup/publish.cmd +++ b/installer/PowerToysSetup/publish.cmd @@ -8,10 +8,10 @@ SET VCToolsVersion=!VCToolsVersion! SET ClearDevCommandPromptEnvVars=false rem In case of Release we should not use Debug CRT in VCRT forwarders -msbuild !PTRoot!\src\modules\previewpane\MonacoPreviewHandler\MonacoPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml +msbuild !PTRoot!\src\modules\previewpane\MonacoPreviewHandler\MonacoPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0 -msbuild !PTRoot!\src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml +msbuild !PTRoot!\src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0 -msbuild !PTRoot!\src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml +msbuild !PTRoot!\src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0 -msbuild !PTRoot!\src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml +msbuild !PTRoot!\src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0 diff --git a/src/Common.Dotnet.CsWinRT.props b/src/Common.Dotnet.CsWinRT.props index 300041b168..63b40dc66a 100644 --- a/src/Common.Dotnet.CsWinRT.props +++ b/src/Common.Dotnet.CsWinRT.props @@ -4,8 +4,8 @@ - 10.0.22621.57 - net9.0-windows10.0.22621.0 + 10.0.26100.68-preview + net9.0-windows10.0.26100.0 10.0.19041.0 10.0.19041.0 win-x64;win-arm64 diff --git a/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj b/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj index 859bbc3116..c3e9e4f3f1 100644 --- a/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj +++ b/src/modules/CropAndLock/CropAndLock/CropAndLock.vcxproj @@ -10,7 +10,7 @@ {f5e1146e-b7b3-4e11-85fd-270a500bd78c} Win32Proj CropAndLock - 10.0.22621.0 + 10.0.26100.0 10.0.19041.0 diff --git a/src/modules/FileLocksmith/FileLocksmithUI/Properties/PublishProfiles/InstallationPublishProfile.pubxml b/src/modules/FileLocksmith/FileLocksmithUI/Properties/PublishProfiles/InstallationPublishProfile.pubxml index cff222baf4..86771137b4 100644 --- a/src/modules/FileLocksmith/FileLocksmithUI/Properties/PublishProfiles/InstallationPublishProfile.pubxml +++ b/src/modules/FileLocksmith/FileLocksmithUI/Properties/PublishProfiles/InstallationPublishProfile.pubxml @@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. FileSystem - net9.0-windows10.0.22621.0 + net9.0-windows10.0.26100.0 10.0.19041.0 10.0.19041.0 $(PowerToysRoot)\$(Platform)\$(Configuration)\WinUI3Apps diff --git a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj index 41a968dbae..28b1dd8db7 100644 --- a/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj +++ b/src/modules/MeasureTool/MeasureToolCore/PowerToys.MeasureToolCore.vcxproj @@ -1,7 +1,7 @@  - + true @@ -139,7 +139,7 @@ - + @@ -150,8 +150,8 @@ - - + + diff --git a/src/modules/MeasureTool/MeasureToolCore/packages.config b/src/modules/MeasureTool/MeasureToolCore/packages.config index f6fdf954c9..9e58941250 100644 --- a/src/modules/MeasureTool/MeasureToolCore/packages.config +++ b/src/modules/MeasureTool/MeasureToolCore/packages.config @@ -3,6 +3,6 @@ - + \ No newline at end of file diff --git a/src/modules/NewPlus/NewShellExtensionContextMenu.win10/NewPlus.ShellExtension.win10.vcxproj b/src/modules/NewPlus/NewShellExtensionContextMenu.win10/NewPlus.ShellExtension.win10.vcxproj index 38d8f640f0..16c6b4efbc 100644 --- a/src/modules/NewPlus/NewShellExtensionContextMenu.win10/NewPlus.ShellExtension.win10.vcxproj +++ b/src/modules/NewPlus/NewShellExtensionContextMenu.win10/NewPlus.ShellExtension.win10.vcxproj @@ -9,7 +9,7 @@ Win32Proj {0db0f63a-d2f8-4da3-a650-2d0b8724218e} NewPlusShellExtensionWin10 - 10.0.22621.0 + 10.0.26100.0 diff --git a/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/Directory.Packages.props b/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/Directory.Packages.props index 2439092e9c..f1605f92ed 100644 --- a/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/Directory.Packages.props +++ b/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/Directory.Packages.props @@ -6,9 +6,9 @@ - + - + diff --git a/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/TemplateCmdPalExtension/TemplateCmdPalExtension.csproj b/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/TemplateCmdPalExtension/TemplateCmdPalExtension.csproj index 644599cc90..ae3035a498 100644 --- a/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/TemplateCmdPalExtension/TemplateCmdPalExtension.csproj +++ b/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/TemplateCmdPalExtension/TemplateCmdPalExtension.csproj @@ -4,8 +4,8 @@ TemplateCmdPalExtension app.manifest - 10.0.22621.57 - net9.0-windows10.0.22621.0 + 10.0.26100.68-preview + net9.0-windows10.0.26100.0 10.0.19041.0 10.0.19041.0 win-x64;win-arm64 diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs index 13aae5a81b..476f50511a 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/MainWindow.xaml.cs @@ -57,7 +57,11 @@ public sealed partial class MainWindow : WindowEx, InitializeComponent(); _hwnd = new HWND(WinRT.Interop.WindowNative.GetWindowHandle(this).ToInt32()); - CommandPaletteHost.SetHostHwnd((ulong)_hwnd.Value); + + unsafe + { + CommandPaletteHost.SetHostHwnd((ulong)_hwnd.Value); + } _keyboardListener = new KeyboardListener(); _keyboardListener.Start(); diff --git a/src/modules/cmdpal/Microsoft.Terminal.UI/Microsoft.Terminal.UI.vcxproj b/src/modules/cmdpal/Microsoft.Terminal.UI/Microsoft.Terminal.UI.vcxproj index 43c890dd31..4f13f17ed6 100644 --- a/src/modules/cmdpal/Microsoft.Terminal.UI/Microsoft.Terminal.UI.vcxproj +++ b/src/modules/cmdpal/Microsoft.Terminal.UI/Microsoft.Terminal.UI.vcxproj @@ -19,7 +19,7 @@ false Windows Store 10.0 - 10.0.22621.0 + 10.0.26100.0 10.0.19041.0 diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Programs/UWPApplication.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Programs/UWPApplication.cs index 4619bd70c9..0915ea05dc 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Programs/UWPApplication.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Programs/UWPApplication.cs @@ -221,11 +221,10 @@ public class UWPApplication : IProgram var capacity = 1024U; PWSTR outBuffer = new PWSTR((char*)(void*)Marshal.AllocHGlobal((int)capacity * sizeof(char))); var source = $"@{{{packageFullName}? {parsed}}}"; - void* reserved = null; try { - PInvoke.SHLoadIndirectString(source, outBuffer, capacity, ref reserved).ThrowOnFailure(); + PInvoke.SHLoadIndirectString(source, outBuffer.AsSpan()).ThrowOnFailure(); var loaded = outBuffer.ToString(); return string.IsNullOrEmpty(loaded) ? string.Empty : loaded; @@ -235,7 +234,7 @@ public class UWPApplication : IProgram try { var sourceFallback = $"@{{{packageFullName}?{parsedFallback}}}"; - PInvoke.SHLoadIndirectString(sourceFallback, outBuffer, capacity, ref reserved).ThrowOnFailure(); + PInvoke.SHLoadIndirectString(sourceFallback, outBuffer.AsSpan()).ThrowOnFailure(); var loaded = outBuffer.ToString(); return string.IsNullOrEmpty(loaded) ? string.Empty : loaded; } diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Actions/ActionRuntimeFactory.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Actions/ActionRuntimeFactory.cs new file mode 100644 index 0000000000..8457910fc6 --- /dev/null +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Actions/ActionRuntimeFactory.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Microsoft.CmdPal.Ext.Indexer.Native; +using Windows.Win32; +using Windows.Win32.Foundation; +using Windows.Win32.System.Com; +using WinRT; +using WinRT.Interop; + +namespace Microsoft.CmdPal.Ext.Indexer.Data; + +internal static class ActionRuntimeFactory +{ + private const string ActionRuntimeClsidStr = "C36FEF7E-35F3-4192-9F2C-AF1FD425FB85"; + + // typeof(Windows.AI.Actions.IActionRuntime).GUID + private static readonly Guid IActionRuntimeIID = Guid.Parse("206EFA2C-C909-508A-B4B0-9482BE96DB9C"); + + public static unsafe global::Windows.AI.Actions.ActionRuntime CreateActionRuntime() + { + IntPtr abiPtr = default; + try + { + Guid classId = Guid.Parse(ActionRuntimeClsidStr); + Guid iid = IActionRuntimeIID; + + var hresult = NativeMethods.CoCreateInstance(ref Unsafe.AsRef(in classId), IntPtr.Zero, NativeHelpers.CLSCTXLOCALSERVER, ref iid, out abiPtr); + Marshal.ThrowExceptionForHR((int)hresult); + + return MarshalInterface.FromAbi(abiPtr); + } + finally + { + MarshalInspectable.DisposeAbi(abiPtr); + } + } +} diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Assets/Actions.png b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Assets/Actions.png new file mode 100644 index 0000000000000000000000000000000000000000..6aaddfda8555193d9b29e6066f0817497271e7b1 GIT binary patch literal 4408 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 InvokeAsync() + { + try + { + await actionInstance.InvokeAsync(); + return CommandResult.GoHome(); + } + catch (Exception ex) + { + return CommandResult.ShowToast("Failed to invoke action " + actionInstance.Definition.Id + ": " + ex.Message); + } + } +} diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Data/IndexerListItem.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Data/IndexerListItem.cs index 57d399b668..f2bfbc1c1a 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Data/IndexerListItem.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Data/IndexerListItem.cs @@ -4,8 +4,11 @@ using System.Collections.Generic; using Microsoft.CmdPal.Ext.Indexer.Commands; +using Microsoft.CmdPal.Ext.Indexer.Pages; using Microsoft.CmdPal.Ext.Indexer.Properties; +using Microsoft.CommandPalette.Extensions; using Microsoft.CommandPalette.Extensions.Toolkit; +using Windows.Foundation.Metadata; namespace Microsoft.CmdPal.Ext.Indexer.Data; @@ -38,9 +41,24 @@ internal sealed partial class IndexerListItem : ListItem } } - MoreCommands = [ + IContextItem[] moreCommands = [ ..context, - new CommandContextItem(new OpenWithCommand(indexerItem)), + new CommandContextItem(new OpenWithCommand(indexerItem))]; + + if (ApiInformation.IsApiContractPresent("Windows.AI.Actions.ActionsContract", 4)) + { + var actionsListContextItem = new ActionsListContextItem(indexerItem.FullPath); + if (actionsListContextItem.AnyActions()) + { + moreCommands = [ + .. moreCommands, + actionsListContextItem + ]; + } + } + + MoreCommands = [ + .. moreCommands, new CommandContextItem(new ShowFileInFolderCommand(indexerItem.FullPath) { Name = Resources.Indexer_Command_ShowInFolder }), new CommandContextItem(new CopyPathCommand(indexerItem)), new CommandContextItem(new OpenInConsoleCommand(indexerItem)), diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Microsoft.CmdPal.Ext.Indexer.csproj b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Microsoft.CmdPal.Ext.Indexer.csproj index 73102cbc31..53f871d6b0 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Microsoft.CmdPal.Ext.Indexer.csproj +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Microsoft.CmdPal.Ext.Indexer.csproj @@ -34,6 +34,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Native/NativeHelpers.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Native/NativeHelpers.cs index e7d7f2ca75..8ef2536a35 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Native/NativeHelpers.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Native/NativeHelpers.cs @@ -11,6 +11,7 @@ public sealed partial class NativeHelpers public const uint SEEMASKINVOKEIDLIST = 12; public const uint CLSCTXINPROCALL = 0x17; + public const uint CLSCTXLOCALSERVER = 0x4; public struct PropertyKeys { diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/NativeMethods.json b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/NativeMethods.json index aa6eed881c..02fff599f2 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/NativeMethods.json +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/NativeMethods.json @@ -1,6 +1,7 @@ { "$schema": "https://aka.ms/CsWin32.schema.json", "allowMarshaling": false, - "emitSingleFile": false, - "public": true + "comInterop": { + "preserveSigMethods": [ "*" ] + } } diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Pages/ActionsListContextItem.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Pages/ActionsListContextItem.cs new file mode 100644 index 0000000000..d191a5a08c --- /dev/null +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Pages/ActionsListContextItem.cs @@ -0,0 +1,93 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Globalization; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CmdPal.Ext.Indexer.Commands; +using Microsoft.CmdPal.Ext.Indexer.Data; +using Microsoft.CmdPal.Ext.Indexer.Properties; +using Microsoft.CommandPalette.Extensions.Toolkit; +using Windows.AI.Actions; +using Windows.System; + +namespace Microsoft.CmdPal.Ext.Indexer.Pages; + +internal sealed partial class ActionsListContextItem : CommandContextItem +{ + private readonly string fullPath; + private readonly List actions = []; + private static readonly Lock UpdateMoreCommandsLock = new(); + private static ActionRuntime actionRuntime; + + public ActionsListContextItem(string fullPath) + : base(new NoOpCommand()) + { + Title = Resources.Indexer_Command_Actions; + Icon = Icons.Actions; + RequestedShortcut = KeyChordHelpers.FromModifiers(alt: true, vkey: VirtualKey.A); + this.fullPath = fullPath; + UpdateMoreCommands(); + } + + public bool AnyActions() => actions.Count != 0; + + private void ActionCatalog_Changed(global::Windows.AI.Actions.Hosting.ActionCatalog sender, object args) + { + UpdateMoreCommands(); + } + + private void UpdateMoreCommands() + { + try + { + lock (UpdateMoreCommandsLock) + { + if (actionRuntime == null) + { + actionRuntime = ActionRuntimeFactory.CreateActionRuntime(); + Task.Delay(500).Wait(); + } + + actionRuntime.ActionCatalog.Changed -= ActionCatalog_Changed; + actionRuntime.ActionCatalog.Changed += ActionCatalog_Changed; + } + + var extension = System.IO.Path.GetExtension(fullPath).ToLower(CultureInfo.InvariantCulture); + ActionEntity entity = null; + if (extension != null) + { + if (extension == ".jpg" || extension == ".jpeg" || extension == ".png") + { + entity = actionRuntime.EntityFactory.CreatePhotoEntity(fullPath); + } + else if (extension == ".docx" || extension == ".doc" || extension == ".pdf" || extension == ".txt") + { + entity = actionRuntime.EntityFactory.CreateDocumentEntity(fullPath); + } + } + + if (entity == null) + { + entity = actionRuntime.EntityFactory.CreateFileEntity(fullPath); + } + + lock (actions) + { + actions.Clear(); + foreach (var actionInstance in actionRuntime.ActionCatalog.GetActionsForInputs([entity])) + { + actions.Add(new CommandContextItem(new ExecuteActionCommand(actionInstance))); + } + + MoreCommands = [.. actions]; + } + } + catch + { + actionRuntime = null; + } + } +} diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Pages/Icons.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Pages/Icons.cs index a55cbe506e..a07bce2016 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Pages/Icons.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Pages/Icons.cs @@ -12,6 +12,8 @@ internal sealed class Icons internal static IconInfo FileExplorer { get; } = IconHelpers.FromRelativePath("Assets\\FileExplorer.png"); + internal static IconInfo Actions { get; } = IconHelpers.FromRelativePath("Assets\\Actions.png"); + internal static IconInfo OpenFile { get; } = new("\uE8E5"); // OpenFile internal static IconInfo Document { get; } = new("\uE8A5"); // Document diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.Designer.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.Designer.cs index 37a53c1cef..f5d1ba2d61 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.Designer.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.Designer.cs @@ -60,6 +60,15 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties { } } + /// + /// Looks up a localized string similar to Actions. + /// + internal static string Indexer_Command_Actions { + get { + return ResourceManager.GetString("Indexer_Command_Actions", resourceCulture); + } + } + /// /// Looks up a localized string similar to Browse. /// diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.resx b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.resx index 8e4f70bc1a..61d51998b2 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.resx +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.resx @@ -138,6 +138,9 @@ Open with + + Actions... + Show in folder diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/DefaultBrowserInfo.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/DefaultBrowserInfo.cs index b3df3fc492..646cda1142 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/DefaultBrowserInfo.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/DefaultBrowserInfo.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Runtime.InteropServices; using System.Text; using System.Threading; using ManagedCommon; @@ -188,17 +189,20 @@ public static class DefaultBrowserInfo { var buffer = stackalloc char[128]; var capacity = 128; - void* reserved = null; + var firstChar = str[0]; + var strPtr = &firstChar; // S_OK == 0 - if (global::Windows.Win32.PInvoke.SHLoadIndirectString( - str, + fixed (char* pszSourceLocal = str) + { + if (global::Windows.Win32.PInvoke.SHLoadIndirectString( + pszSourceLocal, buffer, (uint)capacity, - ref reserved) - == 0) - { - return new string(buffer); + default) == 0) + { + return new string(buffer); + } } } diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Utilities.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Utilities.cs index ca88c11c0f..50e56bdefb 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Utilities.cs +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Utilities.cs @@ -37,7 +37,7 @@ public class Utilities var FOLDERID_LocalAppData = new Guid("F1B32785-6FBA-4FCF-9D55-7B8E7F157091"); var hr = PInvoke.SHGetKnownFolderPath( FOLDERID_LocalAppData, - (uint)KNOWN_FOLDER_FLAG.KF_FLAG_FORCE_APP_DATA_REDIRECTION, + KNOWN_FOLDER_FLAG.KF_FLAG_FORCE_APP_DATA_REDIRECTION, null, out var localAppDataFolder); diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.vcxproj b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.vcxproj index 5383686a55..e620524c77 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.vcxproj +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.vcxproj @@ -4,7 +4,7 @@ ..\..\..\..\..\ $(PathToRoot)packages\Microsoft.WindowsAppSDK.1.7.250513003 $(PathToRoot)packages\Microsoft.Windows.CppWinRT.2.0.240111.5 - $(PathToRoot)packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.2428 + $(PathToRoot)packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188 $(PathToRoot)packages\Microsoft.Web.WebView2.1.0.2903.40 @@ -24,7 +24,7 @@ Windows Store 10.0 10.0.19041.0 - 10.0.22621.0 + 10.0.26100.0 diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/packages.config b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/packages.config index 6a27f0cdda..fc2bc5a5df 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/packages.config +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/packages.config @@ -2,6 +2,6 @@ - + \ No newline at end of file diff --git a/src/modules/peek/Peek.FilePreviewer/Controls/ShellPreviewHandlerControl.xaml.cs b/src/modules/peek/Peek.FilePreviewer/Controls/ShellPreviewHandlerControl.xaml.cs index c02582db5d..b7e2652335 100644 --- a/src/modules/peek/Peek.FilePreviewer/Controls/ShellPreviewHandlerControl.xaml.cs +++ b/src/modules/peek/Peek.FilePreviewer/Controls/ShellPreviewHandlerControl.xaml.cs @@ -4,7 +4,6 @@ using System; using System.Runtime.CompilerServices; - using CommunityToolkit.Mvvm.ComponentModel; using Microsoft.UI; using Microsoft.UI.Xaml; @@ -24,8 +23,8 @@ namespace Peek.FilePreviewer.Controls private static readonly COLORREF LightThemeBgColor = new(0x00f3f3f3); private static readonly COLORREF DarkThemeBgColor = new(0x00202020); - private static readonly HBRUSH LightThemeBgBrush = PInvoke.CreateSolidBrush(LightThemeBgColor); - private static readonly HBRUSH DarkThemeBgBrush = PInvoke.CreateSolidBrush(DarkThemeBgColor); + private static readonly HBRUSH LightThemeBgBrush = PInvoke_FilePreviewer.CreateSolidBrush(LightThemeBgColor); + private static readonly HBRUSH DarkThemeBgBrush = PInvoke_FilePreviewer.CreateSolidBrush(DarkThemeBgColor); [ObservableProperty] private IPreviewHandler? source; @@ -88,19 +87,19 @@ namespace Peek.FilePreviewer.Controls if (HandlerVisibility == Visibility.Visible) { - PInvoke.ShowWindow(containerHwnd, SHOW_WINDOW_CMD.SW_SHOW); + PInvoke_FilePreviewer.ShowWindow(containerHwnd, SHOW_WINDOW_CMD.SW_SHOW); IsEnabled = true; // Clears the background from the last previewer // The brush can only be drawn here because flashes will occur during resize - PInvoke.SetClassLongPtr(containerHwnd, GET_CLASS_LONG_INDEX.GCLP_HBRBACKGROUND, containerBgBrush); - PInvoke.UpdateWindow(containerHwnd); - PInvoke.SetClassLongPtr(containerHwnd, GET_CLASS_LONG_INDEX.GCLP_HBRBACKGROUND, IntPtr.Zero); - PInvoke.InvalidateRect(containerHwnd, (RECT*)null, true); + PInvoke_FilePreviewer.SetClassLongPtr(containerHwnd, GET_CLASS_LONG_INDEX.GCLP_HBRBACKGROUND, containerBgBrush); + PInvoke_FilePreviewer.UpdateWindow(containerHwnd); + PInvoke_FilePreviewer.SetClassLongPtr(containerHwnd, GET_CLASS_LONG_INDEX.GCLP_HBRBACKGROUND, IntPtr.Zero); + PInvoke_FilePreviewer.InvalidateRect(containerHwnd, (RECT*)null, true); } else { - PInvoke.ShowWindow(containerHwnd, SHOW_WINDOW_CMD.SW_HIDE); + PInvoke_FilePreviewer.ShowWindow(containerHwnd, SHOW_WINDOW_CMD.SW_HIDE); IsEnabled = false; } } @@ -132,14 +131,14 @@ namespace Peek.FilePreviewer.Controls visuals.SetTextColor(fgColor); // Changing the previewer colors might not always redraw itself - PInvoke.InvalidateRect(containerHwnd, (RECT*)null, true); + PInvoke_FilePreviewer.InvalidateRect(containerHwnd, (RECT*)null, true); } } private LRESULT ContainerWndProc(HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam) { // Here for future use :) - return PInvoke.DefWindowProc(hWnd, msg, wParam, lParam); + return PInvoke_FilePreviewer.DefWindowProc(hWnd, msg, wParam, lParam); } private void EnsureContainerHwndCreated() @@ -157,14 +156,14 @@ namespace Peek.FilePreviewer.Controls fixed (char* pContainerClassName = "PeekShellPreviewHandlerContainer") { - PInvoke.RegisterClass(new WNDCLASSW() + PInvoke_FilePreviewer.RegisterClass(new WNDCLASSW() { lpfnWndProc = containerWndProc, lpszClassName = pContainerClassName, }); // Create the container window to host the preview handler - containerHwnd = PInvoke.CreateWindowEx( + containerHwnd = PInvoke_FilePreviewer.CreateWindowEx( WINDOW_EX_STYLE.WS_EX_LAYERED, pContainerClassName, null, @@ -178,7 +177,7 @@ namespace Peek.FilePreviewer.Controls HINSTANCE.Null); // Allows the preview handlers to display properly - PInvoke.SetLayeredWindowAttributes(containerHwnd, default, byte.MaxValue, LAYERED_WINDOW_ATTRIBUTES_FLAGS.LWA_ALPHA); + PInvoke_FilePreviewer.SetLayeredWindowAttributes(containerHwnd, default, byte.MaxValue, LAYERED_WINDOW_ATTRIBUTES_FLAGS.LWA_ALPHA); } } @@ -186,12 +185,12 @@ namespace Peek.FilePreviewer.Controls { EnsureContainerHwndCreated(); - var dpi = (float)PInvoke.GetDpiForWindow(containerHwnd) / 96; + var dpi = (float)PInvoke_FilePreviewer.GetDpiForWindow(containerHwnd) / 96; // Resize the container window - PInvoke.SetWindowPos( + PInvoke_FilePreviewer.SetWindowPos( containerHwnd, - (HWND)0, // HWND_TOP + (HWND)(nint)0, // HWND_TOP (int)(Math.Abs(args.EffectiveViewport.X) * dpi), (int)(Math.Abs(args.EffectiveViewport.Y) * dpi), (int)(ActualWidth * dpi), @@ -210,7 +209,7 @@ namespace Peek.FilePreviewer.Controls } // Resizing the previewer might not always redraw itself - PInvoke.InvalidateRect(containerHwnd, (RECT*)null, false); + PInvoke_FilePreviewer.InvalidateRect(containerHwnd, (RECT*)null, false); } private void UserControl_GotFocus(object sender, RoutedEventArgs e) diff --git a/src/modules/peek/Peek.FilePreviewer/NativeMethods.json b/src/modules/peek/Peek.FilePreviewer/NativeMethods.json index dc43b58861..b5347f1336 100644 --- a/src/modules/peek/Peek.FilePreviewer/NativeMethods.json +++ b/src/modules/peek/Peek.FilePreviewer/NativeMethods.json @@ -1,4 +1,5 @@ { - "$schema": "https://aka.ms/CsWin32.schema.json", - "public": false + "$schema": "https://aka.ms/CsWin32.schema.json", + "public": false, + "className": "PInvoke_FilePreviewer" } \ No newline at end of file diff --git a/src/modules/peek/Peek.FilePreviewer/Previewers/ShellPreviewHandlerPreviewer/Helpers/IStreamWrapper.cs b/src/modules/peek/Peek.FilePreviewer/Previewers/ShellPreviewHandlerPreviewer/Helpers/IStreamWrapper.cs index 91783781e3..acf54e9f91 100644 --- a/src/modules/peek/Peek.FilePreviewer/Previewers/ShellPreviewHandlerPreviewer/Helpers/IStreamWrapper.cs +++ b/src/modules/peek/Peek.FilePreviewer/Previewers/ShellPreviewHandlerPreviewer/Helpers/IStreamWrapper.cs @@ -53,9 +53,9 @@ namespace Peek.FilePreviewer.Previewers.Helpers } } - public void Seek(long dlibMove, STREAM_SEEK dwOrigin, [Optional] ulong* plibNewPosition) + public void Seek(long dlibMove, SeekOrigin dwOrigin, [Optional] ulong* plibNewPosition) { - long position = Stream.Seek(dlibMove, (SeekOrigin)dwOrigin); + long position = Stream.Seek(dlibMove, dwOrigin); if (plibNewPosition != null) { *plibNewPosition = (ulong)position; @@ -82,7 +82,7 @@ namespace Peek.FilePreviewer.Previewers.Helpers throw new NotSupportedException(); } - public void LockRegion(ulong libOffset, ulong cb, uint dwLockType) + public void LockRegion(ulong libOffset, ulong cb, LOCKTYPE dwLockType) { throw new NotSupportedException(); } @@ -92,7 +92,7 @@ namespace Peek.FilePreviewer.Previewers.Helpers throw new NotSupportedException(); } - public void Stat(STATSTG* pstatstg, uint grfStatFlag) + public void Stat(STATSTG* pstatstg, STATFLAG grfStatFlag) { throw new NotSupportedException(); } diff --git a/src/modules/peek/Peek.FilePreviewer/Previewers/ShellPreviewHandlerPreviewer/ShellPreviewHandlerPreviewer.cs b/src/modules/peek/Peek.FilePreviewer/Previewers/ShellPreviewHandlerPreviewer/ShellPreviewHandlerPreviewer.cs index 248a18ec2c..a6dd66c91f 100644 --- a/src/modules/peek/Peek.FilePreviewer/Previewers/ShellPreviewHandlerPreviewer/ShellPreviewHandlerPreviewer.cs +++ b/src/modules/peek/Peek.FilePreviewer/Previewers/ShellPreviewHandlerPreviewer/ShellPreviewHandlerPreviewer.cs @@ -93,7 +93,7 @@ namespace Peek.FilePreviewer.Previewers // TODO: Figure out how to get it to run in a low integrity level if (!HandlerFactories.TryGetValue(clsid, out var factory)) { - var hr = PInvoke.CoGetClassObject(clsid, CLSCTX.CLSCTX_LOCAL_SERVER, null, typeof(IClassFactory).GUID, out var pFactory); + var hr = PInvoke_FilePreviewer.CoGetClassObject(clsid, CLSCTX.CLSCTX_LOCAL_SERVER, null, typeof(IClassFactory).GUID, out var pFactory); Marshal.ThrowExceptionForHR(hr); // Storing the factory in memory helps makes the handlers load faster @@ -149,7 +149,7 @@ namespace Peek.FilePreviewer.Previewers } else if (previewHandler is IInitializeWithItem initWithItem) { - var hr = PInvoke.SHCreateItemFromParsingName(FileItem.Path, null, typeof(IShellItem).GUID, out var item); + var hr = PInvoke_FilePreviewer.SHCreateItemFromParsingName(FileItem.Path, null, typeof(IShellItem).GUID, out var item); Marshal.ThrowExceptionForHR(hr); initWithItem.Initialize((IShellItem)item, STGM_READ); diff --git a/src/modules/peek/Peek.UI/Extensions/HWNDExtensions.cs b/src/modules/peek/Peek.UI/Extensions/HWNDExtensions.cs index 2a29aadb70..54df9dab21 100644 --- a/src/modules/peek/Peek.UI/Extensions/HWNDExtensions.cs +++ b/src/modules/peek/Peek.UI/Extensions/HWNDExtensions.cs @@ -48,21 +48,21 @@ namespace Peek.UI.Extensions internal static HWND FindChildWindow(this HWND windowHandle, string className) { - return PInvoke.FindWindowEx(windowHandle, HWND.Null, className, null); + return PInvoke_PeekUI.FindWindowEx(windowHandle, HWND.Null, className, null); } internal static Size GetMonitorSize(this HWND hwnd) { - var monitor = PInvoke.MonitorFromWindow(hwnd, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST); + var monitor = PInvoke_PeekUI.MonitorFromWindow(hwnd, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST); MONITORINFO info = default(MONITORINFO); info.cbSize = 40; - PInvoke.GetMonitorInfo(monitor, ref info); + PInvoke_PeekUI.GetMonitorInfo(monitor, ref info); return new Size(info.rcMonitor.Size.Width, info.rcMonitor.Size.Height); } internal static double GetMonitorScale(this HWND hwnd) { - var dpi = PInvoke.GetDpiForWindow(hwnd); + var dpi = PInvoke_PeekUI.GetDpiForWindow(hwnd); var scalingFactor = dpi / 96d; return scalingFactor; } diff --git a/src/modules/peek/Peek.UI/Extensions/WindowExtensions.cs b/src/modules/peek/Peek.UI/Extensions/WindowExtensions.cs index 0112a3877c..393f07c20b 100644 --- a/src/modules/peek/Peek.UI/Extensions/WindowExtensions.cs +++ b/src/modules/peek/Peek.UI/Extensions/WindowExtensions.cs @@ -28,12 +28,12 @@ namespace Peek.UI.Extensions // If the window is maximized, restore to normal state before change its size var placement = default(WINDOWPLACEMENT); - if (PInvoke.GetWindowPlacement(hwndToCenter, ref placement)) + if (PInvoke_PeekUI.GetWindowPlacement(hwndToCenter, ref placement)) { if (placement.showCmd == SHOW_WINDOW_CMD.SW_MAXIMIZE) { placement.showCmd = SHOW_WINDOW_CMD.SW_SHOWNORMAL; - if (!PInvoke.SetWindowPlacement(hwndToCenter, in placement)) + if (!PInvoke_PeekUI.SetWindowPlacement(hwndToCenter, in placement)) { Logger.LogError($"SetWindowPlacement failed with error {Marshal.GetLastWin32Error()}"); } @@ -44,12 +44,12 @@ namespace Peek.UI.Extensions Logger.LogError($"GetWindowPlacement failed with error {Marshal.GetLastWin32Error()}"); } - var monitor = PInvoke.MonitorFromWindow(hwndDesktop, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST); + var monitor = PInvoke_PeekUI.MonitorFromWindow(hwndDesktop, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST); MONITORINFO info = default(MONITORINFO); info.cbSize = 40; - PInvoke.GetMonitorInfo(monitor, ref info); - var dpi = PInvoke.GetDpiForWindow(new HWND(hwndDesktop)); - PInvoke.GetWindowRect(hwndToCenter, out RECT windowRect); + PInvoke_PeekUI.GetMonitorInfo(monitor, ref info); + var dpi = PInvoke_PeekUI.GetDpiForWindow(new HWND((nint)hwndDesktop)); + PInvoke_PeekUI.GetWindowRect(hwndToCenter, out RECT windowRect); var scalingFactor = dpi / 96d; var w = width.HasValue ? (int)(width * scalingFactor) : windowRect.right - windowRect.left; var h = height.HasValue ? (int)(height * scalingFactor) : windowRect.bottom - windowRect.top; @@ -63,7 +63,7 @@ namespace Peek.UI.Extensions private static void SetWindowPosOrThrow(HWND hWnd, HWND hWndInsertAfter, int x, int y, int cx, int cy, SET_WINDOW_POS_FLAGS uFlags) { - bool result = PInvoke.SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags); + bool result = PInvoke_PeekUI.SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags); if (!result) { Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error()); diff --git a/src/modules/peek/Peek.UI/Helpers/FileExplorerHelper.cs b/src/modules/peek/Peek.UI/Helpers/FileExplorerHelper.cs index 466ae85028..fb57e80047 100644 --- a/src/modules/peek/Peek.UI/Helpers/FileExplorerHelper.cs +++ b/src/modules/peek/Peek.UI/Helpers/FileExplorerHelper.cs @@ -58,7 +58,7 @@ namespace Peek.UI.Helpers object? oNull2 = null; var serviceProvider = (IServiceProvider)shellWindows.FindWindowSW(ref oNull1, ref oNull2, SWC_DESKTOP, out int pHWND, SWFO_NEEDDISPATCH); - var shellBrowser = (IShellBrowser)serviceProvider.QueryService(PInvoke.SID_STopLevelBrowser, typeof(IShellBrowser).GUID); + var shellBrowser = (IShellBrowser)serviceProvider.QueryService(PInvoke_PeekUI.SID_STopLevelBrowser, typeof(IShellBrowser).GUID); IShellItemArray? shellItemArray = GetShellItemArray(shellBrowser, onlySelectedFiles); return shellItemArray; @@ -81,7 +81,7 @@ namespace Peek.UI.Helpers if (webBrowserApp.HWND == foregroundWindowHandle) { var serviceProvider = (IServiceProvider)webBrowserApp; - var shellBrowser = (IShellBrowser)serviceProvider.QueryService(PInvoke.SID_STopLevelBrowser, typeof(IShellBrowser).GUID); + var shellBrowser = (IShellBrowser)serviceProvider.QueryService(PInvoke_PeekUI.SID_STopLevelBrowser, typeof(IShellBrowser).GUID); shellBrowser.GetWindow(out IntPtr shellBrowserHandle); if (activeTab == shellBrowserHandle) @@ -122,7 +122,7 @@ namespace Peek.UI.Helpers GUITHREADINFO guiThreadInfo = new() { cbSize = (uint)Marshal.SizeOf() }; // Get information for the foreground thread - if (PInvoke.GetGUIThreadInfo(0, ref guiThreadInfo)) + if (PInvoke_PeekUI.GetGUIThreadInfo(0, ref guiThreadInfo)) { return guiThreadInfo.hwndActive == hwnd && (guiThreadInfo.flags & GUITHREADINFO_FLAGS.GUI_CARETBLINKING) != 0; } diff --git a/src/modules/peek/Peek.UI/NativeMethods.json b/src/modules/peek/Peek.UI/NativeMethods.json new file mode 100644 index 0000000000..ff8e941bec --- /dev/null +++ b/src/modules/peek/Peek.UI/NativeMethods.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://aka.ms/CsWin32.schema.json", + "public": false, + "className": "PInvoke_PeekUI" +} \ No newline at end of file diff --git a/src/modules/peek/Peek.UI/PeekXAML/App.xaml.cs b/src/modules/peek/Peek.UI/PeekXAML/App.xaml.cs index a433b00e43..9b753b3224 100644 --- a/src/modules/peek/Peek.UI/PeekXAML/App.xaml.cs +++ b/src/modules/peek/Peek.UI/PeekXAML/App.xaml.cs @@ -128,7 +128,7 @@ namespace Peek.UI { // Need to read the foreground HWND before activating Peek to avoid focus stealing // Foreground HWND must always be Explorer or Desktop - var foregroundWindowHandle = Windows.Win32.PInvoke.GetForegroundWindow(); + var foregroundWindowHandle = Windows.Win32.PInvoke_PeekUI.GetForegroundWindow(); bool firstActivation = false; diff --git a/src/modules/peek/Peek.UI/PeekXAML/MainWindow.xaml.cs b/src/modules/peek/Peek.UI/PeekXAML/MainWindow.xaml.cs index 03e48c5ceb..3ce9a82bf9 100644 --- a/src/modules/peek/Peek.UI/PeekXAML/MainWindow.xaml.cs +++ b/src/modules/peek/Peek.UI/PeekXAML/MainWindow.xaml.cs @@ -213,7 +213,7 @@ namespace Peek.UI /// PreviewSizeChangedArgs private void FilePreviewer_PreviewSizeChanged(object sender, PreviewSizeChangedArgs e) { - var foregroundWindowHandle = Windows.Win32.PInvoke.GetForegroundWindow(); + var foregroundWindowHandle = Windows.Win32.PInvoke_PeekUI.GetForegroundWindow(); var monitorSize = foregroundWindowHandle.GetMonitorSize(); var monitorScale = foregroundWindowHandle.GetMonitorScale(); diff --git a/src/modules/powerrename/PowerRename.FuzzingTest/PowerRename.FuzzingTest.vcxproj b/src/modules/powerrename/PowerRename.FuzzingTest/PowerRename.FuzzingTest.vcxproj index 63ba1028a4..a40c363194 100644 --- a/src/modules/powerrename/PowerRename.FuzzingTest/PowerRename.FuzzingTest.vcxproj +++ b/src/modules/powerrename/PowerRename.FuzzingTest/PowerRename.FuzzingTest.vcxproj @@ -6,7 +6,7 @@ Win32Proj {2694e2fb-dcd5-4bff-a418-b6c3c7ce3b8e} Test - 10.0.22621.0 + 10.0.26100.0 PowerRename.FuzzingTest diff --git a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj index e124c83726..9587b0dac0 100644 --- a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj +++ b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj @@ -1,7 +1,7 @@  - + true @@ -205,7 +205,7 @@ - + @@ -218,8 +218,8 @@ - - + + diff --git a/src/modules/powerrename/PowerRenameUILib/packages.config b/src/modules/powerrename/PowerRenameUILib/packages.config index 268846b6a0..4a91705aea 100644 --- a/src/modules/powerrename/PowerRenameUILib/packages.config +++ b/src/modules/powerrename/PowerRenameUILib/packages.config @@ -5,6 +5,6 @@ - + \ No newline at end of file