Compare commits

..

22 Commits

Author SHA1 Message Date
vanzue
e0ab7812e3 bring icon back 2025-05-15 09:41:24 +08:00
Yu Leng
4d5f843c47 update 2025-05-13 16:46:18 +08:00
Yu Leng
fc5299d0cc update 2025-05-13 15:15:46 +08:00
Yu Leng (from Dev Box)
ebe82c0224 update 2025-05-12 17:37:32 +08:00
Yu Leng (from Dev Box)
5b4a6743db init 2025-05-12 16:40:24 +08:00
Yu Leng (from Dev Box)
b74dc04b3b update 2025-05-12 16:40:19 +08:00
Yu Leng
86318e09a4 Fix bug 2025-05-12 11:22:19 +08:00
Yu Leng
123d00e77b update 2025-05-09 17:36:14 +08:00
Yu Leng
2e2e4432b0 update 2025-05-09 14:52:03 +08:00
Yu Leng
1db5a21944 update 2025-05-09 10:27:02 +08:00
Yu Leng (from Dev Box)
264839b470 init 2025-05-06 15:59:59 +08:00
Mike Griese
371b7f0868 CmdPal: Cloak the window instead of hiding it (#39170)
This avoids the few frames of "flicker in" that XAML does when the window is SW_SHOW'n

closes #38384
closes #38404
closes #38438
2025-05-05 13:34:20 -05:00
Niels Laute
b6bcc92eb4 [CmdPal] MinWidth/Height and DPI-aware launch dimensions (#38637)
* MinWidth/Height and DPI-aware launch dimensions

* Making MainWindow DPI aware too

* Moving toastwindow to WinUIEx too

* Update MainWindow.xaml.cs

* Reverting back to the working logic

* Localizing settings window title

* Xaml formatting

* Update SettingsWindow.xaml.cs
2025-05-05 18:44:28 +02:00
Davide Giacometti
2ac464279a [CmdPal] Prevent maximizing (#39220)
Prevent CmdPal window from maximizing when user double-click the title bar area.

 Closes: #39096
2025-05-04 06:04:29 -05:00
Mike Griese
8ce198a47b cmdpal: fix a leak in the extension template (#39209)
There's apparently a footgun with the way we're using ComServer, which
results in us leaking the extension processes when we think we've
disposed them

The fix unfortunately has to be on the extension side. Extensions
published prior to 0.2 will need to manually fix this.

closes: #39045
2025-05-04 06:04:09 -05:00
Mike Griese
15ef9189ba cmdpal: unset the command if we don't find a command (#39208)
On a reload, the system commands fallback would leave the "restart"
fallback behind, for the same reason as what we found around
e40372c & ef264d9 in #38455
2025-05-04 06:03:01 -05:00
Mike Griese
2c555e2c2b Dismiss the details pane when the list gets emptied (#39206)
I cannot find an issue for this. I swear I filed it somewhere.

If you open winget, search for "terminal", wait till it loads, then
hit `esc`, we'll clear the search and empty the list, but never actually
hide the details pane. That looks weird.

This fixes that.

Closes _nothing i guess_.
2025-05-04 06:02:38 -05:00
Jerry Xu
83817700e1 [Infra-BuildScript] Add PowerShell Script to Enforce Shared Common.Dotnet.CsWinRT.props in all CSharp Projects under Src Sub-Folder (#37811)
* Add Powershell script to validate whether CSharp project correctly import shared props, update pipeline to enforce such validation, and fixed all projects that didn't import this shared props correctly

* add common props for fuzz test project

* update the path

* Only scans projects in src sub-folder

* Update .pipelines/verifyCommonProps.ps1

* Update csproj to include Common.Dotnet.CsWinRT.props

* Fix indentation in RegistryPreview.FuzzTests.csproj

* exclude TemplateCmdPalExtension.csproj in validation process

* exclude TemplateCmdPalExtension.csproj in validation process

---------

Co-authored-by: Leilei Zhang <leilzh@microsoft.com>
Co-authored-by: Jerry Xu <nxu@microsoft.com>
2025-05-02 20:38:11 -07:00
Mike Griese
7e92a9a5e9 CmdPal: Start extensions in parallel (#39203)
This reduces our extension startup time by approximately 70% on my
machine (I have 17 extensions). I'd guess the gains scale with the
number of extensions. That's 8s -> 3s on average, and now I also get 2.5s reloads.

This retains the order of the list of extensions, by only starting the
processes in parallel. Once we have all the command provider instances,
then actually retrieving the commands.

It also adds a timeout on startup & load, so that one misbehaving extension won't block everyone else.

closes: #38529
2025-05-02 19:43:31 -05:00
Niels Laute
fe067def65 Fix for missing CmdPal extensions docs (#39173) 2025-05-01 18:33:01 +00:00
Yu Leng
6b9c99c2f6 [cmdpal][AOT] clean up some AOT related issue (#39163)
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2025-04-30 22:53:06 +08:00
Yu Leng
ba6af794ac [cmdpal] Support search any file in fallback command (#38455)
## Summary of the Pull Request
1. Add new setting to control this behaviour
2. Support always on and only when file exist in the fallback command
3. Change the condition of updateFallbackCommand in toplevelvm

demo:

https://github.com/user-attachments/assets/19e4ced3-30ad-44f4-8f3a-93620f46bb3d


## PR Checklist

- [x] **Closes:** #38370

---------

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
2025-04-30 06:30:23 -05:00
93 changed files with 1247 additions and 2201 deletions

View File

@@ -344,6 +344,11 @@ jobs:
flattenFolders: True
OverWrite: True
# Check if all projects (located in src sub-folder) import common props
- pwsh: |-
& '.pipelines/verifyCommonProps.ps1' -sourceDir '$(build.sourcesdirectory)\src'
displayName: Audit shared common props for CSharp projects in src sub-folder
# Check if deps.json files don't reference different dll versions.
- pwsh: |-
& '.pipelines/verifyDepsJsonLibraryVersions.ps1' -targetDir '$(build.sourcesdirectory)\$(BuildPlatform)\$(BuildConfiguration)'

View File

@@ -0,0 +1,54 @@
[CmdletBinding()]
Param(
[Parameter(Mandatory = $True, Position = 1)]
[string]$sourceDir
)
# scan all csharp project in the source directory
function Get-CSharpProjects {
param (
[string]$path
)
# Get all .csproj files under the specified path
return Get-ChildItem -Path $path -Recurse -Filter *.csproj | Select-Object -ExpandProperty FullName
}
# Check if the project file imports 'Common.Dotnet.CsWinRT.props'
function Test-ImportSharedCsWinRTProps {
param (
[string]$filePath
)
# Load the XML content of the .csproj file
[xml]$csprojContent = Get-Content -Path $filePath
# Check if the Import element with Project attribute containing 'Common.Dotnet.CsWinRT.props' exists
return $csprojContent.Project.Import | Where-Object { $null -ne $_.Project -and $_.Project.EndsWith('Common.Dotnet.CsWinRT.props') }
}
# Call the function with the provided source directory
$csprojFilesArray = Get-CSharpProjects -path $sourceDir
$hasInvalidCsProj = $false
# Enumerate the array of file paths and call Validate-ImportSharedCsWinRTProps for each file
foreach ($csprojFile in $csprojFilesArray) {
# Skip if the file ends with 'TemplateCmdPalExtension.csproj'
if ($csprojFile -like '*TemplateCmdPalExtension.csproj') {
continue
}
$importExists = Test-ImportSharedCsWinRTProps -filePath $csprojFile
if (!$importExists) {
Write-Output "$csprojFile need to import 'Common.Dotnet.CsWinRT.props'."
$hasInvalidCsProj = $true
}
}
if ($hasInvalidCsProj) {
exit 1
}
exit 0

View File

@@ -624,20 +624,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CommandPalette", "CommandPa
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Built-in Extensions", "Built-in Extensions", "{ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Apps", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.Apps\Microsoft.CmdPal.Ext.Apps.csproj", "{6CE438DF-C245-4997-A360-0A0939E4BA34}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Bookmarks", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.Bookmark\Microsoft.CmdPal.Ext.Bookmarks.csproj", "{E09AA983-C755-474F-83D6-A5CDF528C070}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Calc", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.Calc\Microsoft.CmdPal.Ext.Calc.csproj", "{6D56B64D-FF1F-488F-AFED-9B9854A5D399}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Registry", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.Registry\Microsoft.CmdPal.Ext.Registry.csproj", "{92EC89E4-9972-453A-8A1A-3A9E230C146A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.WindowsServices", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WindowsServices\Microsoft.CmdPal.Ext.WindowsServices.csproj", "{51939B4F-1F62-4BFF-A6A2-C08646E5BE95}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.WindowsSettings", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WindowsSettings\Microsoft.CmdPal.Ext.WindowsSettings.csproj", "{D1160404-D3D1-497A-883A-4059C07C2273}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.WindowsTerminal", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WindowsTerminal\Microsoft.CmdPal.Ext.WindowsTerminal.csproj", "{40F6D69D-E321-400F-A767-5628C7AE453D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extension SDK", "Extension SDK", "{F3D09629-59A2-4924-A4B9-D6BFAA2C1B49}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.CommandPalette.Extensions", "src\modules\cmdpal\extensionsdk\Microsoft.CommandPalette.Extensions\Microsoft.CommandPalette.Extensions.vcxproj", "{305DD37E-C85D-4B08-AAFE-7381FA890463}"
@@ -660,8 +646,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.UI", "src\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.UI.ViewModels", "src\modules\cmdpal\Microsoft.CmdPal.UI.ViewModels\Microsoft.CmdPal.UI.ViewModels.csproj", "{C66020D1-CB10-4CF7-8715-84C97FD5E5E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.ClipboardHistory", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.ClipboardHistory\Microsoft.CmdPal.Ext.ClipboardHistory.csproj", "{79775343-7A3D-445D-9104-3DD5B2893DF9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CmdPalModuleInterface", "src\modules\cmdpal\CmdPalModuleInterface\CmdPalModuleInterface.vcxproj", "{0ADEB797-C8C7-4FFA-ACD5-2AF6CAD7ECD8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkspacesCsharpLibrary", "src\modules\Workspaces\WorkspacesCsharpLibrary\WorkspacesCsharpLibrary.csproj", "{89D0E199-B17A-418C-B2F8-7375B6708357}"
@@ -672,12 +656,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Indexe
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.Shell", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.Shell\Microsoft.CmdPal.Ext.Shell.csproj", "{C0CE3B5E-16D3-495D-B335-CA791B660162}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CmdPal.Ext.WindowWalker", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WindowWalker\Microsoft.CmdPal.Ext.WindowWalker.csproj", "{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WebSearch", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WebSearch\Microsoft.CmdPal.Ext.WebSearch.csproj", "{605E914B-7232-4789-AF46-BF5D3DDFC14E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WinGet", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.WinGet\Microsoft.CmdPal.Ext.WinGet.csproj", "{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvancedPaste.UnitTests", "src\modules\AdvancedPaste\AdvancedPaste.UnitTests\AdvancedPaste.UnitTests.csproj", "{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvancedPaste.FuzzTests", "src\modules\AdvancedPaste\AdvancedPaste.FuzzTests\AdvancedPaste.FuzzTests.csproj", "{7F5B9557-5878-4438-A721-3E28296BA193}"
@@ -690,8 +668,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZoomItModuleInterface", "sr
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZoomItSettingsInterop", "src\modules\ZoomIt\ZoomItSettingsInterop\ZoomItSettingsInterop.vcxproj", "{CA7D8106-30B9-4AEC-9D05-B69B31B8C461}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.TimeDate", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.TimeDate\Microsoft.CmdPal.Ext.TimeDate.csproj", "{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UITestAutomation", "src\common\UITestAutomation\UITestAutomation.csproj", "{A558C25D-2007-498E-8B6F-43405AFAE9E2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeyboardManagerEditorUI", "src\modules\keyboardmanager\KeyboardManagerEditorUI\KeyboardManagerEditorUI.csproj", "{08F9155D-B6DC-46E5-9C83-AF60B655898B}"
@@ -704,8 +680,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hosts.UITests", "src\module
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegistryPreview.FuzzTests", "src\modules\registrypreview\RegistryPreview.FuzzTests\RegistryPreview.FuzzTests.csproj", "{5702B3CC-8575-48D5-83D8-15BB42269CD3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.System", "src\modules\cmdpal\ext\Microsoft.CmdPal.Ext.System\Microsoft.CmdPal.Ext.System.csproj", "{64B88F02-CD88-4ED8-9624-989A800230F9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CmdPalKeyboardService", "src\modules\cmdpal\CmdPalKeyboardService\CmdPalKeyboardService.vcxproj", "{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerRename.FuzzingTest", "src\modules\powerrename\PowerRename.FuzzingTest\PowerRename.FuzzingTest.vcxproj", "{2694E2FB-DCD5-4BFF-A418-B6C3C7CE3B8E}"
@@ -2262,62 +2236,6 @@ Global
{66614C26-314C-4B91-9071-76133422CFEF}.Release|ARM64.Build.0 = Release|ARM64
{66614C26-314C-4B91-9071-76133422CFEF}.Release|x64.ActiveCfg = Release|x64
{66614C26-314C-4B91-9071-76133422CFEF}.Release|x64.Build.0 = Release|x64
{6CE438DF-C245-4997-A360-0A0939E4BA34}.Debug|ARM64.ActiveCfg = Debug|ARM64
{6CE438DF-C245-4997-A360-0A0939E4BA34}.Debug|ARM64.Build.0 = Debug|ARM64
{6CE438DF-C245-4997-A360-0A0939E4BA34}.Debug|x64.ActiveCfg = Debug|x64
{6CE438DF-C245-4997-A360-0A0939E4BA34}.Debug|x64.Build.0 = Debug|x64
{6CE438DF-C245-4997-A360-0A0939E4BA34}.Release|ARM64.ActiveCfg = Release|ARM64
{6CE438DF-C245-4997-A360-0A0939E4BA34}.Release|ARM64.Build.0 = Release|ARM64
{6CE438DF-C245-4997-A360-0A0939E4BA34}.Release|x64.ActiveCfg = Release|x64
{6CE438DF-C245-4997-A360-0A0939E4BA34}.Release|x64.Build.0 = Release|x64
{E09AA983-C755-474F-83D6-A5CDF528C070}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E09AA983-C755-474F-83D6-A5CDF528C070}.Debug|ARM64.Build.0 = Debug|ARM64
{E09AA983-C755-474F-83D6-A5CDF528C070}.Debug|x64.ActiveCfg = Debug|x64
{E09AA983-C755-474F-83D6-A5CDF528C070}.Debug|x64.Build.0 = Debug|x64
{E09AA983-C755-474F-83D6-A5CDF528C070}.Release|ARM64.ActiveCfg = Release|ARM64
{E09AA983-C755-474F-83D6-A5CDF528C070}.Release|ARM64.Build.0 = Release|ARM64
{E09AA983-C755-474F-83D6-A5CDF528C070}.Release|x64.ActiveCfg = Release|x64
{E09AA983-C755-474F-83D6-A5CDF528C070}.Release|x64.Build.0 = Release|x64
{6D56B64D-FF1F-488F-AFED-9B9854A5D399}.Debug|ARM64.ActiveCfg = Debug|ARM64
{6D56B64D-FF1F-488F-AFED-9B9854A5D399}.Debug|ARM64.Build.0 = Debug|ARM64
{6D56B64D-FF1F-488F-AFED-9B9854A5D399}.Debug|x64.ActiveCfg = Debug|x64
{6D56B64D-FF1F-488F-AFED-9B9854A5D399}.Debug|x64.Build.0 = Debug|x64
{6D56B64D-FF1F-488F-AFED-9B9854A5D399}.Release|ARM64.ActiveCfg = Release|ARM64
{6D56B64D-FF1F-488F-AFED-9B9854A5D399}.Release|ARM64.Build.0 = Release|ARM64
{6D56B64D-FF1F-488F-AFED-9B9854A5D399}.Release|x64.ActiveCfg = Release|x64
{6D56B64D-FF1F-488F-AFED-9B9854A5D399}.Release|x64.Build.0 = Release|x64
{92EC89E4-9972-453A-8A1A-3A9E230C146A}.Debug|ARM64.ActiveCfg = Debug|ARM64
{92EC89E4-9972-453A-8A1A-3A9E230C146A}.Debug|ARM64.Build.0 = Debug|ARM64
{92EC89E4-9972-453A-8A1A-3A9E230C146A}.Debug|x64.ActiveCfg = Debug|x64
{92EC89E4-9972-453A-8A1A-3A9E230C146A}.Debug|x64.Build.0 = Debug|x64
{92EC89E4-9972-453A-8A1A-3A9E230C146A}.Release|ARM64.ActiveCfg = Release|ARM64
{92EC89E4-9972-453A-8A1A-3A9E230C146A}.Release|ARM64.Build.0 = Release|ARM64
{92EC89E4-9972-453A-8A1A-3A9E230C146A}.Release|x64.ActiveCfg = Release|x64
{92EC89E4-9972-453A-8A1A-3A9E230C146A}.Release|x64.Build.0 = Release|x64
{51939B4F-1F62-4BFF-A6A2-C08646E5BE95}.Debug|ARM64.ActiveCfg = Debug|ARM64
{51939B4F-1F62-4BFF-A6A2-C08646E5BE95}.Debug|ARM64.Build.0 = Debug|ARM64
{51939B4F-1F62-4BFF-A6A2-C08646E5BE95}.Debug|x64.ActiveCfg = Debug|x64
{51939B4F-1F62-4BFF-A6A2-C08646E5BE95}.Debug|x64.Build.0 = Debug|x64
{51939B4F-1F62-4BFF-A6A2-C08646E5BE95}.Release|ARM64.ActiveCfg = Release|ARM64
{51939B4F-1F62-4BFF-A6A2-C08646E5BE95}.Release|ARM64.Build.0 = Release|ARM64
{51939B4F-1F62-4BFF-A6A2-C08646E5BE95}.Release|x64.ActiveCfg = Release|x64
{51939B4F-1F62-4BFF-A6A2-C08646E5BE95}.Release|x64.Build.0 = Release|x64
{D1160404-D3D1-497A-883A-4059C07C2273}.Debug|ARM64.ActiveCfg = Debug|ARM64
{D1160404-D3D1-497A-883A-4059C07C2273}.Debug|ARM64.Build.0 = Debug|ARM64
{D1160404-D3D1-497A-883A-4059C07C2273}.Debug|x64.ActiveCfg = Debug|x64
{D1160404-D3D1-497A-883A-4059C07C2273}.Debug|x64.Build.0 = Debug|x64
{D1160404-D3D1-497A-883A-4059C07C2273}.Release|ARM64.ActiveCfg = Release|ARM64
{D1160404-D3D1-497A-883A-4059C07C2273}.Release|ARM64.Build.0 = Release|ARM64
{D1160404-D3D1-497A-883A-4059C07C2273}.Release|x64.ActiveCfg = Release|x64
{D1160404-D3D1-497A-883A-4059C07C2273}.Release|x64.Build.0 = Release|x64
{40F6D69D-E321-400F-A767-5628C7AE453D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{40F6D69D-E321-400F-A767-5628C7AE453D}.Debug|ARM64.Build.0 = Debug|ARM64
{40F6D69D-E321-400F-A767-5628C7AE453D}.Debug|x64.ActiveCfg = Debug|x64
{40F6D69D-E321-400F-A767-5628C7AE453D}.Debug|x64.Build.0 = Debug|x64
{40F6D69D-E321-400F-A767-5628C7AE453D}.Release|ARM64.ActiveCfg = Release|ARM64
{40F6D69D-E321-400F-A767-5628C7AE453D}.Release|ARM64.Build.0 = Release|ARM64
{40F6D69D-E321-400F-A767-5628C7AE453D}.Release|x64.ActiveCfg = Release|x64
{40F6D69D-E321-400F-A767-5628C7AE453D}.Release|x64.Build.0 = Release|x64
{305DD37E-C85D-4B08-AAFE-7381FA890463}.Debug|ARM64.ActiveCfg = Debug|ARM64
{305DD37E-C85D-4B08-AAFE-7381FA890463}.Debug|ARM64.Build.0 = Debug|ARM64
{305DD37E-C85D-4B08-AAFE-7381FA890463}.Debug|x64.ActiveCfg = Debug|x64
@@ -2394,14 +2312,6 @@ Global
{C66020D1-CB10-4CF7-8715-84C97FD5E5E2}.Release|ARM64.Build.0 = Release|ARM64
{C66020D1-CB10-4CF7-8715-84C97FD5E5E2}.Release|x64.ActiveCfg = Release|x64
{C66020D1-CB10-4CF7-8715-84C97FD5E5E2}.Release|x64.Build.0 = Release|x64
{79775343-7A3D-445D-9104-3DD5B2893DF9}.Debug|ARM64.ActiveCfg = Debug|ARM64
{79775343-7A3D-445D-9104-3DD5B2893DF9}.Debug|ARM64.Build.0 = Debug|ARM64
{79775343-7A3D-445D-9104-3DD5B2893DF9}.Debug|x64.ActiveCfg = Debug|x64
{79775343-7A3D-445D-9104-3DD5B2893DF9}.Debug|x64.Build.0 = Debug|x64
{79775343-7A3D-445D-9104-3DD5B2893DF9}.Release|ARM64.ActiveCfg = Release|ARM64
{79775343-7A3D-445D-9104-3DD5B2893DF9}.Release|ARM64.Build.0 = Release|ARM64
{79775343-7A3D-445D-9104-3DD5B2893DF9}.Release|x64.ActiveCfg = Release|x64
{79775343-7A3D-445D-9104-3DD5B2893DF9}.Release|x64.Build.0 = Release|x64
{0ADEB797-C8C7-4FFA-ACD5-2AF6CAD7ECD8}.Debug|ARM64.ActiveCfg = Debug|ARM64
{0ADEB797-C8C7-4FFA-ACD5-2AF6CAD7ECD8}.Debug|ARM64.Build.0 = Debug|ARM64
{0ADEB797-C8C7-4FFA-ACD5-2AF6CAD7ECD8}.Debug|x64.ActiveCfg = Debug|x64
@@ -2446,34 +2356,6 @@ Global
{C0CE3B5E-16D3-495D-B335-CA791B660162}.Release|ARM64.Build.0 = Release|ARM64
{C0CE3B5E-16D3-495D-B335-CA791B660162}.Release|x64.ActiveCfg = Release|x64
{C0CE3B5E-16D3-495D-B335-CA791B660162}.Release|x64.Build.0 = Release|x64
{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C}.Debug|ARM64.ActiveCfg = Debug|ARM64
{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C}.Debug|ARM64.Build.0 = Debug|ARM64
{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C}.Debug|x64.ActiveCfg = Debug|x64
{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C}.Debug|x64.Build.0 = Debug|x64
{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C}.Release|ARM64.ActiveCfg = Release|ARM64
{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C}.Release|ARM64.Build.0 = Release|ARM64
{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C}.Release|x64.ActiveCfg = Release|x64
{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C}.Release|x64.Build.0 = Release|x64
{605E914B-7232-4789-AF46-BF5D3DDFC14E}.Debug|ARM64.ActiveCfg = Debug|ARM64
{605E914B-7232-4789-AF46-BF5D3DDFC14E}.Debug|ARM64.Build.0 = Debug|ARM64
{605E914B-7232-4789-AF46-BF5D3DDFC14E}.Debug|x64.ActiveCfg = Debug|x64
{605E914B-7232-4789-AF46-BF5D3DDFC14E}.Debug|x64.Build.0 = Debug|x64
{605E914B-7232-4789-AF46-BF5D3DDFC14E}.Release|ARM64.ActiveCfg = Release|ARM64
{605E914B-7232-4789-AF46-BF5D3DDFC14E}.Release|ARM64.Build.0 = Release|ARM64
{605E914B-7232-4789-AF46-BF5D3DDFC14E}.Release|x64.ActiveCfg = Release|x64
{605E914B-7232-4789-AF46-BF5D3DDFC14E}.Release|x64.Build.0 = Release|x64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Debug|ARM64.Build.0 = Debug|ARM64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Debug|ARM64.Deploy.0 = Debug|ARM64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Debug|x64.ActiveCfg = Debug|x64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Debug|x64.Build.0 = Debug|x64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Debug|x64.Deploy.0 = Debug|x64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Release|ARM64.ActiveCfg = Release|ARM64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Release|ARM64.Build.0 = Release|ARM64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Release|ARM64.Deploy.0 = Release|ARM64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Release|x64.ActiveCfg = Release|x64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Release|x64.Build.0 = Release|x64
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9}.Release|x64.Deploy.0 = Release|x64
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Debug|ARM64.ActiveCfg = Debug|ARM64
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Debug|ARM64.Build.0 = Debug|ARM64
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE}.Debug|x64.ActiveCfg = Debug|x64
@@ -2514,18 +2396,6 @@ Global
{CA7D8106-30B9-4AEC-9D05-B69B31B8C461}.Release|ARM64.Build.0 = Release|ARM64
{CA7D8106-30B9-4AEC-9D05-B69B31B8C461}.Release|x64.ActiveCfg = Release|x64
{CA7D8106-30B9-4AEC-9D05-B69B31B8C461}.Release|x64.Build.0 = Release|x64
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}.Debug|ARM64.ActiveCfg = Debug|ARM64
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}.Debug|ARM64.Build.0 = Debug|ARM64
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}.Debug|ARM64.Deploy.0 = Debug|ARM64
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}.Debug|x64.ActiveCfg = Debug|x64
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}.Debug|x64.Build.0 = Debug|x64
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}.Debug|x64.Deploy.0 = Debug|x64
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}.Release|ARM64.ActiveCfg = Release|ARM64
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}.Release|ARM64.Build.0 = Release|ARM64
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}.Release|ARM64.Deploy.0 = Release|ARM64
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}.Release|x64.ActiveCfg = Release|x64
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}.Release|x64.Build.0 = Release|x64
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449}.Release|x64.Deploy.0 = Release|x64
{A558C25D-2007-498E-8B6F-43405AFAE9E2}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A558C25D-2007-498E-8B6F-43405AFAE9E2}.Debug|ARM64.Build.0 = Debug|ARM64
{A558C25D-2007-498E-8B6F-43405AFAE9E2}.Debug|x64.ActiveCfg = Debug|x64
@@ -2574,14 +2444,6 @@ Global
{5702B3CC-8575-48D5-83D8-15BB42269CD3}.Release|ARM64.Build.0 = Release|ARM64
{5702B3CC-8575-48D5-83D8-15BB42269CD3}.Release|x64.ActiveCfg = Release|x64
{5702B3CC-8575-48D5-83D8-15BB42269CD3}.Release|x64.Build.0 = Release|x64
{64B88F02-CD88-4ED8-9624-989A800230F9}.Debug|ARM64.ActiveCfg = Debug|ARM64
{64B88F02-CD88-4ED8-9624-989A800230F9}.Debug|ARM64.Build.0 = Debug|ARM64
{64B88F02-CD88-4ED8-9624-989A800230F9}.Debug|x64.ActiveCfg = Debug|x64
{64B88F02-CD88-4ED8-9624-989A800230F9}.Debug|x64.Build.0 = Debug|x64
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|ARM64.ActiveCfg = Release|ARM64
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|ARM64.Build.0 = Release|ARM64
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|x64.ActiveCfg = Release|x64
{64B88F02-CD88-4ED8-9624-989A800230F9}.Release|x64.Build.0 = Release|x64
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|ARM64.ActiveCfg = Debug|ARM64
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|ARM64.Build.0 = Debug|ARM64
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2}.Debug|x64.ActiveCfg = Debug|x64
@@ -2825,13 +2687,6 @@ Global
{66614C26-314C-4B91-9071-76133422CFEF} = {B6C42F16-73EB-477E-8B0D-4E6CF6C20AAC}
{3846508C-77EB-4034-A702-F8BB263C4F79} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2} = {3846508C-77EB-4034-A702-F8BB263C4F79}
{6CE438DF-C245-4997-A360-0A0939E4BA34} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{E09AA983-C755-474F-83D6-A5CDF528C070} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{6D56B64D-FF1F-488F-AFED-9B9854A5D399} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{92EC89E4-9972-453A-8A1A-3A9E230C146A} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{51939B4F-1F62-4BFF-A6A2-C08646E5BE95} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{D1160404-D3D1-497A-883A-4059C07C2273} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{40F6D69D-E321-400F-A767-5628C7AE453D} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{F3D09629-59A2-4924-A4B9-D6BFAA2C1B49} = {3846508C-77EB-4034-A702-F8BB263C4F79}
{305DD37E-C85D-4B08-AAFE-7381FA890463} = {F3D09629-59A2-4924-A4B9-D6BFAA2C1B49}
{CA4D810F-C8F4-4B61-9DA9-71807E0B9F24} = {F3D09629-59A2-4924-A4B9-D6BFAA2C1B49}
@@ -2843,29 +2698,23 @@ Global
{7520A2FE-00A2-49B8-83ED-DB216E874C04} = {3846508C-77EB-4034-A702-F8BB263C4F79}
{8FBDABA4-40EE-4C0E-9BC8-2F6444A6EF90} = {7520A2FE-00A2-49B8-83ED-DB216E874C04}
{C66020D1-CB10-4CF7-8715-84C97FD5E5E2} = {7520A2FE-00A2-49B8-83ED-DB216E874C04}
{79775343-7A3D-445D-9104-3DD5B2893DF9} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{0ADEB797-C8C7-4FFA-ACD5-2AF6CAD7ECD8} = {3846508C-77EB-4034-A702-F8BB263C4F79}
{89D0E199-B17A-418C-B2F8-7375B6708357} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{0DB0F63A-D2F8-4DA3-A650-2D0B8724218E} = {CA716AE6-FE5C-40AC-BB8F-2C87912687AC}
{453CBB73-A3CB-4D0B-8D24-6940B86FE21D} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{C0CE3B5E-16D3-495D-B335-CA791B660162} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{3A9A7297-92C4-4F16-B6F9-8D4AB652C86C} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{605E914B-7232-4789-AF46-BF5D3DDFC14E} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{E81A7D20-9862-ABDB-0AAE-9BC5B517A9F9} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{D5E5F5EA-1B6C-4A73-88BE-304F36C9E4EE} = {9873BA05-4C41-4819-9283-CF45D795431B}
{7F5B9557-5878-4438-A721-3E28296BA193} = {9873BA05-4C41-4819-9283-CF45D795431B}
{DD6E12FE-5509-4ABC-ACC2-3D6DC98A238C} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{0A84F764-3A88-44CD-AA96-41BDBD48627B} = {DD6E12FE-5509-4ABC-ACC2-3D6DC98A238C}
{E4585179-2AC1-4D5F-A3FF-CFC5392F694C} = {DD6E12FE-5509-4ABC-ACC2-3D6DC98A238C}
{CA7D8106-30B9-4AEC-9D05-B69B31B8C461} = {DD6E12FE-5509-4ABC-ACC2-3D6DC98A238C}
{DCC6BD67-17BB-47AA-B507-FB0FE43A7449} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{A558C25D-2007-498E-8B6F-43405AFAE9E2} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{08F9155D-B6DC-46E5-9C83-AF60B655898B} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{4382A954-179A-4078-92AF-715187DFFF50} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
{EBED240C-8702-452D-B764-6DB9DA9179AF} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
{4E0AE3A4-2EE0-44D7-A2D0-8769977254A0} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
{5702B3CC-8575-48D5-83D8-15BB42269CD3} = {929C1324-22E8-4412-A9A8-80E85F3985A5}
{64B88F02-CD88-4ED8-9624-989A800230F9} = {ECB8E0D1-7603-4E5C-AB10-D1E545E6F8E2}
{5F63C743-F6CE-4DBA-A200-2B3F8A14E8C2} = {3846508C-77EB-4034-A702-F8BB263C4F79}
{2694E2FB-DCD5-4BFF-A418-B6C3C7CE3B8E} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
EndGlobalSection

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Some items may be set in Directory.Build.props in root -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- OneFuzz does not currently support testing with .NET 9.
As a temporary workaround, create a .NET 8 project and use file links
to include the code that needs testing. -->
<PropertyGroup>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
</PropertyGroup>
</Project>

View File

@@ -28,9 +28,7 @@ namespace ManagedCommon
* If you want to publish it with Native AOT enabled (or publish as a single file).
* You need to find another way to remove Assembly.Location usage.
*/
#pragma warning disable IL3000 // Avoid accessing Assembly file path when publishing as a single file
private static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location).ProductVersion;
#pragma warning restore IL3000 // Avoid accessing Assembly file path when publishing as a single file
private static readonly string Version = "2.0.0.0";
/// <summary>
/// Initializes the logger and sets the path for logging.

View File

@@ -37,17 +37,6 @@ namespace Microsoft.PowerToys.Telemetry
public void WriteEvent<T>(T telemetryEvent)
where T : EventBase, IEvent
{
if (DataDiagnosticsSettings.GetEnabledValue())
{
this.Write<T>(
telemetryEvent.EventName,
new EventSourceOptions()
{
Keywords = ProjectKeywordMeasure,
Tags = ProjectTelemetryTagProductAndServicePerformance,
},
telemetryEvent);
}
}
}
}

View File

@@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- Look at Directory.Build.props in root for common stuff as well -->
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
<Import Project="..\..\..\Common.Dotnet.FuzzTest.props" />
<PropertyGroup>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

View File

@@ -1,6 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- Look at Directory.Build.props in root for common stuff as well -->
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
<Import Project="..\..\..\Common.Dotnet.FuzzTest.props" />
<PropertyGroup>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

View File

@@ -14,11 +14,12 @@ namespace TemplateCmdPalExtension;
public class Program
{
[MTAThread]
public static async Task Main(string[] args)
public static void Main(string[] args)
{
if (args.Length > 0 && args[0] == "-RegisterProcessAsComServer")
{
await using global::Shmuelie.WinRTServer.ComServer server = new();
global::Shmuelie.WinRTServer.ComServer server = new();
ManualResetEvent extensionDisposedEvent = new(false);
// We are instantiating an extension instance once above, and returning it every time the callback in RegisterExtension below is called.
@@ -31,6 +32,8 @@ public class Program
// This will make the main thread wait until the event is signalled by the extension class.
// Since we have single instance of the extension object, we exit as soon as it is disposed.
extensionDisposedEvent.WaitOne();
server.Stop();
server.UnsafeDispose();
}
else
{

View File

@@ -190,7 +190,7 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa
contextItem.SlowInitializeProperties();
});
if (!string.IsNullOrEmpty(model.Command.Name))
if (!string.IsNullOrEmpty(model.Command?.Name))
{
_defaultCommandContextItem = new(new CommandContextItem(model.Command!), PageContext)
{

View File

@@ -5,7 +5,6 @@
using System.Collections.Immutable;
using System.Collections.Specialized;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.Ext.Apps;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
@@ -37,15 +36,6 @@ public partial class MainListPage : DynamicListPage,
// The all apps page will kick off a BG thread to start loading apps.
// We just want to know when it is done.
var allApps = AllAppsCommandProvider.Page;
allApps.PropChanged += (s, p) =>
{
if (p.PropertyName == nameof(allApps.IsLoading))
{
IsLoading = ActuallyLoading();
}
};
WeakReferenceMessenger.Default.Register<ClearSearchMessage>(this);
WeakReferenceMessenger.Default.Register<UpdateFallbackItemsMessage>(this);
@@ -123,8 +113,7 @@ public partial class MainListPage : DynamicListPage,
// with a list of all our commands & apps.
if (_filteredItems == null)
{
IEnumerable<IListItem> apps = AllAppsCommandProvider.Page.GetItems();
_filteredItems = commands.Concat(apps);
_filteredItems = commands;
}
// Produce a list of everything that matches the current filter.
@@ -156,8 +145,7 @@ public partial class MainListPage : DynamicListPage,
private bool ActuallyLoading()
{
var tlcManager = _serviceProvider.GetService<TopLevelCommandManager>()!;
var allApps = AllAppsCommandProvider.Page;
return allApps.IsLoading || tlcManager.IsLoading;
return tlcManager.IsLoading;
}
// Almost verbatim ListHelpers.ScoreListItem, but also accounting for the

View File

@@ -3,8 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Text.Json;
using AdaptiveCards.ObjectModel.WinUI3;
using AdaptiveCards.Templating;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.UI.ViewModels.Models;
@@ -26,121 +24,11 @@ public partial class ContentFormViewModel(IFormContent _form, WeakReference<IPag
public string DataJson { get; protected set; } = "{}";
public AdaptiveCardParseResult? Card { get; private set; }
public override void InitializeProperties()
{
var model = _formModel.Unsafe;
if (model == null)
{
return;
}
try
{
TemplateJson = model.TemplateJson;
StateJson = model.StateJson;
DataJson = model.DataJson;
AdaptiveCardTemplate template = new(TemplateJson);
var cardJson = template.Expand(DataJson);
Card = AdaptiveCard.FromJsonString(cardJson);
}
catch (Exception e)
{
// If we fail to parse the card JSON, then display _our own card_
// with the exception
AdaptiveCardTemplate template = new(ErrorCardJson);
var serializeString = (string? s) => JsonSerializer.Serialize(s, JsonSerializationContext.Default.String);
// todo: we could probably stick Card.Errors in there too
var dataJson = $$"""
{
"error_message": {{serializeString(e.Message)}},
"error_stack": {{serializeString(e.StackTrace)}},
"inner_exception": {{serializeString(e.InnerException?.Message)}},
"template_json": {{serializeString(TemplateJson)}},
"data_json": {{serializeString(DataJson)}}
}
""";
var cardJson = template.Expand(dataJson);
Card = AdaptiveCard.FromJsonString(cardJson);
}
UpdateProperty(nameof(Card));
}
public void HandleSubmit(IAdaptiveActionElement action, JsonObject inputs)
public void HandleSubmit()
{
if (action is AdaptiveOpenUrlAction openUrlAction)
{
WeakReferenceMessenger.Default.Send<LaunchUriMessage>(new(openUrlAction.Url));
return;
}
if (action is AdaptiveSubmitAction or AdaptiveExecuteAction)
{
// Get the data and inputs
var dataString = (action as AdaptiveSubmitAction)?.DataJson.Stringify() ?? string.Empty;
var inputString = inputs.Stringify();
_ = Task.Run(() =>
{
try
{
var model = _formModel.Unsafe!;
if (model != null)
{
var result = model.SubmitForm(inputString, dataString);
WeakReferenceMessenger.Default.Send<HandleCommandResultMessage>(new(new(result)));
}
}
catch (Exception ex)
{
ShowException(ex);
}
});
}
}
private static readonly string ErrorCardJson = """
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.5",
"body": [
{
"type": "TextBlock",
"text": "Error parsing form from extension",
"wrap": true,
"style": "heading",
"size": "ExtraLarge",
"weight": "Bolder",
"color": "Attention"
},
{
"type": "TextBlock",
"wrap": true,
"text": "${error_message}",
"color": "Attention"
},
{
"type": "TextBlock",
"text": "${error_stack}",
"fontType": "Monospace"
},
{
"type": "TextBlock",
"wrap": true,
"text": "Inner exception:"
},
{
"type": "TextBlock",
"wrap": true,
"text": "${inner_exception}",
"color": "Attention"
}
]
}
""";
}

View File

@@ -328,7 +328,19 @@ public partial class ListViewModel : PageViewModel, IDisposable
}
[RelayCommand]
private void UpdateSelectedItem(ListItemViewModel item)
private void UpdateSelectedItem(ListItemViewModel? item)
{
if (item != null)
{
SetSelectedItem(item);
}
else
{
ClearSelectedItem();
}
}
private void SetSelectedItem(ListItemViewModel item)
{
if (!item.SafeSlowInit())
{
@@ -357,6 +369,23 @@ public partial class ListViewModel : PageViewModel, IDisposable
});
}
private void ClearSelectedItem()
{
// GH #322:
// For inexplicable reasons, if you try updating the command bar and
// the details on the same UI thread tick as updating the list, we'll
// explode
DoOnUiThread(
() =>
{
WeakReferenceMessenger.Default.Send<UpdateCommandBarMessage>(new(null));
WeakReferenceMessenger.Default.Send<HideDetailsMessage>();
TextToSuggest = string.Empty;
});
}
public override void InitializeProperties()
{
base.InitializeProperties();

View File

@@ -17,8 +17,6 @@
<ItemGroup>
<PackageReference Include="CommunityToolkit.Common" />
<PackageReference Include="CommunityToolkit.Mvvm" />
<PackageReference Include="AdaptiveCards.Templating" />
<PackageReference Include="AdaptiveCards.ObjectModel.WinUI3" GeneratePathProperty="true" />
<PackageReference Include="Microsoft.Windows.CsWin32">
<PrivateAssets>all</PrivateAssets>
@@ -33,8 +31,6 @@
<ProjectReference Include="..\Microsoft.CmdPal.Common\Microsoft.CmdPal.Common.csproj" />
<ProjectReference Include="..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Apps\Microsoft.CmdPal.Ext.Apps.csproj" />
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
</ItemGroup>
@@ -70,14 +66,14 @@
</ItemGroup>
<!-- Just mark it as AOT compatible. Do not publish with AOT now. We need fully test before we really publish it as AOT enabled-->
<!--<PropertyGroup>
<PropertyGroup>
<SelfContained>true</SelfContained>
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
<PublishTrimmed>true</PublishTrimmed>
<PublishSingleFile>true</PublishSingleFile>
--><!-- <DisableRuntimeMarshalling>true</DisableRuntimeMarshalling> --><!--
<!--<DisableRuntimeMarshalling>true</DisableRuntimeMarshalling>-->
<PublishAot>true</PublishAot>
<EnableMsixTooling>true</EnableMsixTooling>
</PropertyGroup>-->
<EnableMsixTooling>true</EnableMsixTooling>
</PropertyGroup>
</Project>

View File

@@ -4,6 +4,7 @@
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Diagnostics;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
@@ -53,53 +54,44 @@ public partial class TopLevelCommandManager : ObservableObject,
{
CommandProviderWrapper wrapper = new(provider, _taskScheduler);
_builtInCommands.Add(wrapper);
await LoadTopLevelCommandsFromProvider(wrapper);
var commands = await LoadTopLevelCommandsFromProvider(wrapper);
lock (TopLevelCommands)
{
foreach (var c in commands)
{
TopLevelCommands.Add(c);
}
}
}
return true;
}
// May be called from a background thread
private async Task LoadTopLevelCommandsFromProvider(CommandProviderWrapper commandProvider)
private async Task<IEnumerable<TopLevelViewModel>> LoadTopLevelCommandsFromProvider(CommandProviderWrapper commandProvider)
{
WeakReference<IPageContext> weakSelf = new(this);
await commandProvider.LoadTopLevelCommands(_serviceProvider, weakSelf);
var settings = _serviceProvider.GetService<SettingsModel>()!;
var makeAndAdd = (ICommandItem? i, bool fallback) =>
List<TopLevelViewModel> commands = [];
foreach (var item in commandProvider.TopLevelItems)
{
var commandItemViewModel = new CommandItemViewModel(new(i), weakSelf);
var topLevelViewModel = new TopLevelViewModel(commandItemViewModel, fallback, commandProvider.ExtensionHost, commandProvider.ProviderId, settings, _serviceProvider);
commands.Add(item);
}
lock (TopLevelCommands)
{
TopLevelCommands.Add(topLevelViewModel);
}
};
await Task.Factory.StartNew(
() =>
{
lock (TopLevelCommands)
{
foreach (var item in commandProvider.TopLevelItems)
{
TopLevelCommands.Add(item);
}
foreach (var item in commandProvider.FallbackItems)
{
TopLevelCommands.Add(item);
}
}
},
CancellationToken.None,
TaskCreationOptions.None,
_taskScheduler);
foreach (var item in commandProvider.FallbackItems)
{
commands.Add(item);
}
commandProvider.CommandsChanged -= CommandProvider_CommandsChanged;
commandProvider.CommandsChanged += CommandProvider_CommandsChanged;
return commands;
}
// By all accounts, we're already on a background thread (the COM call
@@ -239,25 +231,71 @@ public partial class TopLevelCommandManager : ObservableObject,
private async Task StartExtensionsAndGetCommands(IEnumerable<IExtensionWrapper> extensions)
{
// TODO This most definitely needs a lock
foreach (var extension in extensions)
{
Logger.LogDebug($"Starting {extension.PackageFullName}");
try
{
// start it ...
await extension.StartExtensionAsync();
var timer = new Stopwatch();
timer.Start();
// ... and fetch the command provider from it.
CommandProviderWrapper wrapper = new(extension, _taskScheduler);
_extensionCommandProviders.Add(wrapper);
await LoadTopLevelCommandsFromProvider(wrapper);
}
catch (Exception ex)
// Start all extensions in parallel
var startTasks = extensions.Select(StartExtensionWithTimeoutAsync);
// Wait for all extensions to start
var wrappers = (await Task.WhenAll(startTasks)).Where(wrapper => wrapper != null).Select(w => w!).ToList();
foreach (var wrapper in wrappers)
{
_extensionCommandProviders.Add(wrapper!);
}
// Load the commands from the providers in parallel
var loadTasks = wrappers.Select(LoadCommandsWithTimeoutAsync);
var commandSets = (await Task.WhenAll(loadTasks)).Where(results => results != null).Select(r => r!).ToList();
lock (TopLevelCommands)
{
foreach (var commands in commandSets)
{
Logger.LogError(ex.ToString());
foreach (var c in commands)
{
TopLevelCommands.Add(c);
}
}
}
timer.Stop();
Logger.LogDebug($"Loading extensions took {timer.ElapsedMilliseconds} ms");
}
private async Task<CommandProviderWrapper?> StartExtensionWithTimeoutAsync(IExtensionWrapper extension)
{
Logger.LogDebug($"Starting {extension.PackageFullName}");
try
{
await extension.StartExtensionAsync().WaitAsync(TimeSpan.FromSeconds(10));
return new CommandProviderWrapper(extension, _taskScheduler);
}
catch (Exception ex)
{
Logger.LogError($"Failed to start extension {extension.PackageFullName}: {ex}");
return null; // Return null for failed extensions
}
}
private async Task<IEnumerable<TopLevelViewModel>?> LoadCommandsWithTimeoutAsync(CommandProviderWrapper wrapper)
{
try
{
return await LoadTopLevelCommandsFromProvider(wrapper!).WaitAsync(TimeSpan.FromSeconds(10));
}
catch (TimeoutException)
{
Logger.LogError($"Loading commands from {wrapper!.ExtensionHost?.Extension?.PackageFullName} timed out");
}
catch (Exception ex)
{
Logger.LogError($"Failed to load commands for extension {wrapper!.ExtensionHost?.Extension?.PackageFullName}: {ex}");
}
return null;
}
private void ExtensionService_OnExtensionRemoved(IExtensionService sender, IEnumerable<IExtensionWrapper> extensions)

View File

@@ -2,23 +2,10 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using ManagedCommon;
using Microsoft.CmdPal.Common.Helpers;
using Microsoft.CmdPal.Common.Services;
using Microsoft.CmdPal.Ext.Apps;
using Microsoft.CmdPal.Ext.Bookmarks;
using Microsoft.CmdPal.Ext.Calc;
using Microsoft.CmdPal.Ext.Indexer;
using Microsoft.CmdPal.Ext.Registry;
using Microsoft.CmdPal.Ext.Shell;
using Microsoft.CmdPal.Ext.System;
using Microsoft.CmdPal.Ext.TimeDate;
using Microsoft.CmdPal.Ext.WebSearch;
using Microsoft.CmdPal.Ext.WindowsServices;
using Microsoft.CmdPal.Ext.WindowsSettings;
using Microsoft.CmdPal.Ext.WindowsTerminal;
using Microsoft.CmdPal.Ext.WindowWalker;
using Microsoft.CmdPal.Ext.WinGet;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.CmdPal.UI.ViewModels.BuiltinCommands;
using Microsoft.CmdPal.UI.ViewModels.Models;
@@ -107,43 +94,18 @@ public partial class App : Application
services.AddSingleton(TaskScheduler.FromCurrentSynchronizationContext());
// Built-in Commands. Order matters - this is the order they'll be presented by default.
var allApps = new AllAppsCommandProvider();
services.AddSingleton<ICommandProvider>(allApps);
services.AddSingleton<ICommandProvider, ShellCommandsProvider>();
services.AddSingleton<ICommandProvider, CalculatorCommandProvider>();
services.AddSingleton<ICommandProvider, IndexerCommandsProvider>();
services.AddSingleton<ICommandProvider, BookmarksCommandProvider>();
// TODO GH #527 re-enable the clipboard commands
// services.AddSingleton<ICommandProvider, ClipboardHistoryCommandsProvider>();
services.AddSingleton<ICommandProvider, WindowWalkerCommandsProvider>();
services.AddSingleton<ICommandProvider, WebSearchCommandsProvider>();
// GH #38440: Users might not have WinGet installed! Or they might have
// a ridiculously old version. Or might be running as admin.
// We shouldn't explode in the App ctor if we fail to instantiate an
// instance of PackageManager, which will happen in the static ctor
// for WinGetStatics
try
{
var winget = new WinGetExtensionCommandsProvider();
var callback = allApps.LookupApp;
winget.SetAllLookup(callback);
services.AddSingleton<ICommandProvider>(winget);
}
catch (Exception ex)
{
Logger.LogError("Couldn't load winget");
Logger.LogError(ex.ToString());
}
services.AddSingleton<ICommandProvider, WindowsTerminalCommandsProvider>();
services.AddSingleton<ICommandProvider, WindowsSettingsCommandsProvider>();
services.AddSingleton<ICommandProvider, RegistryCommandsProvider>();
services.AddSingleton<ICommandProvider, WindowsServicesCommandsProvider>();
services.AddSingleton<ICommandProvider, BuiltInsCommandProvider>();
services.AddSingleton<ICommandProvider, TimeDateCommandsProvider>();
services.AddSingleton<ICommandProvider, SystemCommandExtensionProvider>();
// Models
services.AddSingleton<TopLevelCommandManager>();

View File

@@ -1,342 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using AdaptiveCards.Rendering.WinUI3;
namespace Microsoft.CmdPal.UI.Controls;
public sealed class AdaptiveCardsConfig
{
public static AdaptiveHostConfig Light { get; }
public static AdaptiveHostConfig Dark { get; }
static AdaptiveCardsConfig()
{
Light = AdaptiveHostConfig.FromJsonString(LightHostConfigString).HostConfig;
Dark = AdaptiveHostConfig.FromJsonString(DarkHostConfigString).HostConfig;
}
public static readonly string DarkHostConfigString = """
{
"spacing": {
"small": 4,
"default": 8,
"medium": 20,
"large": 30,
"extraLarge": 40,
"padding": 8
},
"separator": {
"lineThickness": 0,
"lineColor": "#C8FFFFFF"
},
"supportsInteractivity": true,
"fontTypes": {
"default": {
"fontFamily": "'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif",
"fontSizes": {
"small": 12,
"default": 12,
"medium": 14,
"large": 20,
"extraLarge": 26
},
"fontWeights": {
"lighter": 200,
"default": 400,
"bolder": 600
}
},
"monospace": {
"fontFamily": "'Courier New', Courier, monospace",
"fontSizes": {
"small": 12,
"default": 12,
"medium": 14,
"large": 18,
"extraLarge": 26
},
"fontWeights": {
"lighter": 200,
"default": 400,
"bolder": 600
}
}
},
"containerStyles": {
"default": {
"backgroundColor": "#00000000",
"borderColor": "#00000000",
"foregroundColors": {
"default": {
"default": "#FFFFFF",
"subtle": "#C8FFFFFF"
},
"accent": {
"default": "#0063B1",
"subtle": "#880063B1"
},
"attention": {
"default": "#FF5555",
"subtle": "#DDFF5555"
},
"good": {
"default": "#54a254",
"subtle": "#DD54a254"
},
"warning": {
"default": "#c3ab23",
"subtle": "#DDc3ab23"
}
}
},
"emphasis": {
"backgroundColor": "#09FFFFFF",
"borderColor": "#09FFFFFF",
"foregroundColors": {
"default": {
"default": "#FFFFFF",
"subtle": "#C8FFFFFF"
},
"accent": {
"default": "#2E89FC",
"subtle": "#882E89FC"
},
"attention": {
"default": "#FF5555",
"subtle": "#DDFF5555"
},
"good": {
"default": "#54a254",
"subtle": "#DD54a254"
},
"warning": {
"default": "#c3ab23",
"subtle": "#DDc3ab23"
}
}
}
},
"imageSizes": {
"small": 16,
"medium": 24,
"large": 32
},
"actions": {
"maxActions": 5,
"spacing": "default",
"buttonSpacing": 8,
"showCard": {
"actionMode": "inline",
"inlineTopMargin": 8
},
"actionsOrientation": "horizontal",
"actionAlignment": "stretch"
},
"adaptiveCard": {
"allowCustomStyle": false
},
"imageSet": {
"imageSize": "medium",
"maxImageHeight": 100
},
"factSet": {
"title": {
"color": "default",
"size": "default",
"isSubtle": false,
"weight": "bolder",
"wrap": true,
"maxWidth": 150
},
"value": {
"color": "default",
"size": "default",
"isSubtle": false,
"weight": "default",
"wrap": true
},
"spacing": 8
},
"textStyles": {
"heading": {
"size": "large",
"weight": "bolder",
"color": "default",
"isSubtle": false,
"fontType": "default"
},
"columnHeader": {
"size": "medium",
"weight": "bolder",
"color": "default",
"isSubtle": false,
"fontType": "default"
}
}
}
""";
public static readonly string LightHostConfigString = """
{
"spacing": {
"small": 4,
"default": 8,
"medium": 20,
"large": 30,
"extraLarge": 40,
"padding": 8
},
"separator": {
"lineThickness": 0,
"lineColor": "#606060"
},
"supportsInteractivity": true,
"fontTypes": {
"default": {
"fontFamily": "'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif",
"fontSizes": {
"small": 12,
"default": 12,
"medium": 14,
"large": 20,
"extraLarge": 26
},
"fontWeights": {
"lighter": 200,
"default": 400,
"bolder": 600
}
},
"monospace": {
"fontFamily": "'Courier New', Courier, monospace",
"fontSizes": {
"small": 12,
"default": 12,
"medium": 14,
"large": 18,
"extraLarge": 26
},
"fontWeights": {
"lighter": 200,
"default": 400,
"bolder": 600
}
}
},
"containerStyles": {
"default": {
"backgroundColor": "#00000000",
"borderColor": "#00000000",
"foregroundColors": {
"default": {
"default": "#E6000000",
"subtle": "#99000000"
},
"accent": {
"default": "#0063B1",
"subtle": "#880063B1"
},
"attention": {
"default": "#C00000",
"subtle": "#DDC00000"
},
"good": {
"default": "#54a254",
"subtle": "#DD54a254"
},
"warning": {
"default": "#c3ab23",
"subtle": "#DDc3ab23"
}
}
},
"emphasis": {
"backgroundColor": "#80F6F6F6",
"borderColor": "#80F6F6F6",
"foregroundColors": {
"default": {
"default": "#E6000000",
"subtle": "#99000000"
},
"accent": {
"default": "#2E89FC",
"subtle": "#882E89FC"
},
"attention": {
"default": "#C00000",
"subtle": "#DDC00000"
},
"good": {
"default": "#54a254",
"subtle": "#DD54a254"
},
"warning": {
"default": "#c3ab23",
"subtle": "#DDc3ab23"
}
}
}
},
"imageSizes": {
"small": 16,
"medium": 24,
"large": 32
},
"actions": {
"maxActions": 5,
"spacing": "default",
"buttonSpacing": 8,
"showCard": {
"actionMode": "inline",
"inlineTopMargin": 8
},
"actionsOrientation": "horizontal",
"actionAlignment": "stretch"
},
"adaptiveCard": {
"allowCustomStyle": false
},
"imageSet": {
"imageSize": "medium",
"maxImageHeight": 100
},
"factSet": {
"title": {
"color": "default",
"size": "default",
"isSubtle": false,
"weight": "bolder",
"wrap": true,
"maxWidth": 150
},
"value": {
"color": "default",
"size": "default",
"isSubtle": false,
"weight": "default",
"wrap": true
},
"spacing": 8
},
"textStyles": {
"heading": {
"size": "large",
"weight": "bolder",
"color": "default",
"isSubtle": false,
"fontType": "default"
},
"columnHeader": {
"size": "medium",
"weight": "bolder",
"color": "default",
"isSubtle": false,
"fontType": "default"
}
}
}
""";
}

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="Microsoft.CmdPal.UI.Controls.ContentFormControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.CmdPal.UI.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
xmlns:viewmodels="using:Microsoft.CmdPal.UI.ViewModels"
Background="Transparent"
mc:Ignorable="d">
<UserControl.Resources>
<ResourceDictionary x:Name="CardOverrideStyles">
<Style x:Key="Adaptive.TextBlock" TargetType="TextBlock">
<Setter Property="IsTextSelectionEnabled" Value="True" />
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="ContentGrid" />
</UserControl>

View File

@@ -1,106 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using AdaptiveCards.ObjectModel.WinUI3;
using AdaptiveCards.Rendering.WinUI3;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.CmdPal.UI.Controls;
public sealed partial class ContentFormControl : UserControl
{
private static readonly AdaptiveCardRenderer _renderer;
private ContentFormViewModel? _viewModel;
// LOAD-BEARING: if you don't hang onto a reference to the RenderedAdaptiveCard
// then the GC might clean it up sometime, even while the card is in the UI
// tree. If this gets GC'd, then it'll revoke our Action handler, and the
// form will do seemingly nothing.
private RenderedAdaptiveCard? _renderedCard;
public ContentFormViewModel? ViewModel { get => _viewModel; set => AttachViewModel(value); }
static ContentFormControl()
{
// We can't use `CardOverrideStyles` here yet, because we haven't called InitializeComponent once.
// But also, the default value isn't `null` here. It's... some other default empty value.
// So clear it out so that we know when the first time we get created is
_renderer = new AdaptiveCardRenderer()
{
OverrideStyles = null,
};
}
public ContentFormControl()
{
this.InitializeComponent();
var lightTheme = ActualTheme == Microsoft.UI.Xaml.ElementTheme.Light;
_renderer.HostConfig = lightTheme ? AdaptiveCardsConfig.Light : AdaptiveCardsConfig.Dark;
// 5% BODGY: if we set this multiple times over the lifetime of the app,
// then the second call will explode, because "CardOverrideStyles is already the child of another element".
// SO only set this once.
if (_renderer.OverrideStyles == null)
{
_renderer.OverrideStyles = CardOverrideStyles;
}
// TODO in the future, we should handle ActualThemeChanged and replace
// our rendered card with one for that theme. But today is not that day
}
private void AttachViewModel(ContentFormViewModel? vm)
{
if (_viewModel != null)
{
_viewModel.PropertyChanged -= ViewModel_PropertyChanged;
}
_viewModel = vm;
if (_viewModel != null)
{
_viewModel.PropertyChanged += ViewModel_PropertyChanged;
var c = _viewModel.Card;
if (c != null)
{
DisplayCard(c);
}
}
}
private void ViewModel_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (ViewModel == null)
{
return;
}
if (e.PropertyName == nameof(ViewModel.Card))
{
var c = ViewModel.Card;
if (c != null)
{
DisplayCard(c);
}
}
}
private void DisplayCard(AdaptiveCardParseResult result)
{
_renderedCard = _renderer.RenderAdaptiveCard(result.AdaptiveCard);
ContentGrid.Children.Clear();
if (_renderedCard.FrameworkElement != null)
{
ContentGrid.Children.Add(_renderedCard.FrameworkElement);
}
_renderedCard.Action += Rendered_Action;
}
private void Rendered_Action(RenderedAdaptiveCard sender, AdaptiveActionEventArgs args) =>
ViewModel?.HandleSubmit(args.Action, args.Inputs.AsJson());
}

View File

@@ -27,7 +27,6 @@
PreviewKeyDown="FilterBox_PreviewKeyDown"
PreviewKeyUp="FilterBox_PreviewKeyUp"
Style="{StaticResource SearchTextBoxStyle}"
Description="{x:Bind CurrentPageViewModel.TextToSuggest, Mode=OneWay}"
TextChanged="FilterBox_TextChanged" />
<!-- Disabled Description="{x:Bind CurrentPageViewModel.TextToSuggest, Mode=OneWay}" for now, needs more work -->
</UserControl>

View File

@@ -12,7 +12,7 @@ public delegate bool IsActive();
public delegate bool FilterAccessibleKeyboardEvents(int key, UIntPtr extraInfo);
public class HotkeySettingsControlHook : IDisposable
public partial class HotkeySettingsControlHook : IDisposable
{
private const int WmKeyDown = 0x100;
private const int WmKeyUp = 0x101;

View File

@@ -5,82 +5,81 @@
using System;
using System.Runtime.InteropServices;
namespace Microsoft.PowerToys.Settings.UI.Helpers
namespace Microsoft.PowerToys.Settings.UI.Helpers;
public static partial class NativeKeyboardHelper
{
internal static class NativeKeyboardHelper
[StructLayout(LayoutKind.Sequential)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
public struct INPUT
{
[StructLayout(LayoutKind.Sequential)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
internal struct INPUT
{
internal INPUTTYPE type;
internal InputUnion data;
public INPUTTYPE type;
public InputUnion data;
internal static int Size
{
get { return Marshal.SizeOf(typeof(INPUT)); }
}
}
[StructLayout(LayoutKind.Explicit)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
internal struct InputUnion
public static int Size
{
[FieldOffset(0)]
internal MOUSEINPUT mi;
[FieldOffset(0)]
internal KEYBDINPUT ki;
[FieldOffset(0)]
internal HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
internal struct MOUSEINPUT
{
internal int dx;
internal int dy;
internal int mouseData;
internal uint dwFlags;
internal uint time;
internal UIntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
internal struct KEYBDINPUT
{
internal short wVk;
internal short wScan;
internal uint dwFlags;
internal int time;
internal UIntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
internal struct HARDWAREINPUT
{
internal int uMsg;
internal short wParamL;
internal short wParamH;
}
internal enum INPUTTYPE : uint
{
INPUT_MOUSE = 0,
INPUT_KEYBOARD = 1,
INPUT_HARDWARE = 2,
}
[Flags]
internal enum KeyEventF
{
KeyDown = 0x0000,
ExtendedKey = 0x0001,
KeyUp = 0x0002,
Unicode = 0x0004,
Scancode = 0x0008,
get { return Marshal.SizeOf<INPUT>(); }
}
}
[StructLayout(LayoutKind.Explicit)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
public struct InputUnion
{
[FieldOffset(0)]
public MOUSEINPUT mi;
[FieldOffset(0)]
public KEYBDINPUT ki;
[FieldOffset(0)]
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
public struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public uint dwFlags;
public uint time;
public UIntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
public struct KEYBDINPUT
{
public short wVk;
public short wScan;
public uint dwFlags;
public int time;
public UIntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
public struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
public enum INPUTTYPE : uint
{
INPUT_MOUSE = 0,
INPUT_KEYBOARD = 1,
INPUT_HARDWARE = 2,
}
[Flags]
public enum KeyEventF
{
KeyDown = 0x0000,
ExtendedKey = 0x0001,
KeyUp = 0x0002,
Unicode = 0x0004,
Scancode = 0x0008,
}
}

View File

@@ -3,11 +3,10 @@
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices;
using System.Text;
namespace Microsoft.PowerToys.Settings.UI.Helpers;
public static class NativeMethods
public static partial class NativeMethods
{
private const int WS_POPUP = 1 << 31; // 0x80000000
internal const int GWL_STYLE = -16;
@@ -17,65 +16,11 @@ public static class NativeMethods
internal const int SW_SHOWMAXIMIZED = 3;
internal const int SW_HIDE = 0;
[DllImport("user32.dll")]
internal static extern IntPtr GetActiveWindow();
[LibraryImport("user32.dll")]
public static partial uint SendInput(uint nInputs, NativeKeyboardHelper.INPUT[] pInputs, int cbSize);
[DllImport("user32.dll")]
internal static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll")]
internal static extern bool GetWindowPlacement(IntPtr hWnd, out WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll")]
internal static extern uint SendInput(uint nInputs, NativeKeyboardHelper.INPUT[] pInputs, int cbSize);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
internal static extern short GetAsyncKeyState(int vKey);
[DllImport("user32.dll", SetLastError = true)]
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
// [DllImport("shell32.dll")]
// internal static extern IntPtr SHBrowseForFolderW(ref ShellGetFolder.BrowseInformation browseInfo);
[DllImport("shell32.dll")]
internal static extern int SHGetPathFromIDListW(IntPtr pidl, IntPtr pszPath);
// [DllImport("Comdlg32.dll", CharSet = CharSet.Unicode)]
// internal static extern bool GetOpenFileName([In, Out] OpenFileName openFileName);
[LibraryImport("user32.dll")]
#pragma warning disable CA1401 // P/Invokes should not be visible
[DllImport("user32.dll")]
public static extern bool ShowWindow(System.IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
public static extern int GetDpiForWindow(System.IntPtr hWnd);
[DllImport("user32.dll")]
public static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern bool AllowSetForegroundWindow(int dwProcessId);
[System.Runtime.InteropServices.DllImport("User32.dll")]
public static extern bool SetForegroundWindow(IntPtr handle);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
public static extern bool FreeLibrary(IntPtr hModule);
public static partial short GetAsyncKeyState(int vKey);
#pragma warning restore CA1401 // P/Invokes should not be visible
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SystemParametersInfo(int uiAction, int uiParam, StringBuilder pvParam, int fWinIni);
public static void SetPopupStyle(IntPtr hwnd)
{
_ = SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_POPUP);
}
}

View File

@@ -5,7 +5,6 @@
xmlns:controls="using:Microsoft.CmdPal.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
x:Name="ShortcutContentControl"
mc:Ignorable="d">
<Grid MinWidth="498" MinHeight="220">
@@ -66,11 +65,6 @@
IsTabStop="{Binding ElementName=ShortcutContentControl, Path=IsWarningAltGr, Mode=OneWay}"
Severity="Warning" />
</Grid>
<tk7controls:MarkdownTextBlock
x:Uid="InvalidShortcutWarningLabel"
Background="Transparent"
FontSize="12"
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
</StackPanel>
</Grid>
</UserControl>

View File

@@ -5,7 +5,6 @@
xmlns:controls="using:Microsoft.CmdPal.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">
@@ -36,10 +35,5 @@
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<tk7controls:MarkdownTextBlock
Grid.Column="1"
VerticalAlignment="Center"
Background="Transparent"
Text="{x:Bind Text}" />
</Grid>
</UserControl>

View File

@@ -12,7 +12,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.CmdPal.UI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="using:CommunityToolkit.WinUI.UI.Controls"
xmlns:viewmodels="using:Microsoft.CmdPal.UI.ViewModels"
Background="Transparent"
mc:Ignorable="d">
@@ -37,37 +36,21 @@
<DataTemplate x:Key="FormContentTemplate" x:DataType="viewmodels:ContentFormViewModel">
<Grid Margin="0,4,4,4" Padding="12,8,8,8">
<cmdPalControls:ContentFormControl ViewModel="{x:Bind}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="MarkdownContentTemplate" x:DataType="viewmodels:ContentMarkdownViewModel">
<Grid Margin="0,4,4,4" Padding="12,8,8,8">
<toolkit:MarkdownTextBlock
Background="Transparent"
Header3FontSize="12"
Header3FontWeight="Normal"
Header3Foreground="{ThemeResource TextFillColorSecondaryBrush}"
IsTextSelectionEnabled="True"
Text="{x:Bind Body, Mode=OneWay}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="NestedFormContentTemplate" x:DataType="viewmodels:ContentFormViewModel">
<Grid>
<cmdPalControls:ContentFormControl ViewModel="{x:Bind}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="NestedMarkdownContentTemplate" x:DataType="viewmodels:ContentMarkdownViewModel">
<Grid>
<toolkit:MarkdownTextBlock
Background="Transparent"
Header3FontSize="12"
Header3FontWeight="Normal"
Header3Foreground="{ThemeResource TextFillColorSecondaryBrush}"
IsTextSelectionEnabled="True"
Text="{x:Bind Body, Mode=OneWay}" />
</Grid>
</DataTemplate>

View File

@@ -124,14 +124,12 @@ public sealed partial class ListPage : Page,
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "VS is too aggressive at pruning methods bound in XAML")]
private void ItemsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ItemsList.SelectedItem is ListItemViewModel item)
var vm = ViewModel;
var li = ItemsList.SelectedItem as ListItemViewModel;
_ = Task.Run(() =>
{
var vm = ViewModel;
_ = Task.Run(() =>
{
vm?.UpdateSelectedItemCommand.Execute(item);
});
}
vm?.UpdateSelectedItemCommand.Execute(li);
});
// There's mysterious behavior here, where the selection seemingly
// changes to _nothing_ when we're backspacing to a single character.

View File

@@ -2,13 +2,6 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.Bookmarks;
using Microsoft.UI.Xaml.Documents;
using Microsoft.Win32;
namespace Microsoft.CmdPal.UI.Helpers;

View File

@@ -1,4 +1,4 @@
<Window
<winuiex:WindowEx
x:Class="Microsoft.CmdPal.UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -6,8 +6,13 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pages="using:Microsoft.CmdPal.UI.Pages"
xmlns:viewmodels="using:Microsoft.CmdPal.UI.ViewModels"
xmlns:winuiex="using:WinUIEx"
Width="800"
Height="480"
MinWidth="320"
MinHeight="240"
Activated="MainWindow_Activated"
Closed="MainWindow_Closed"
mc:Ignorable="d">
<pages:ShellPage x:Name="RootShellPage" />
</Window>
</winuiex:WindowEx>

View File

@@ -25,15 +25,17 @@ using Windows.UI;
using Windows.UI.WindowManagement;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Dwm;
using Windows.Win32.UI.Input.KeyboardAndMouse;
using Windows.Win32.UI.Shell;
using Windows.Win32.UI.WindowsAndMessaging;
using WinRT;
using WinUIEx;
using RS_ = Microsoft.CmdPal.UI.Helpers.ResourceLoaderInstance;
namespace Microsoft.CmdPal.UI;
public sealed partial class MainWindow : Window,
public sealed partial class MainWindow : WindowEx,
IRecipient<DismissMessage>,
IRecipient<ShowWindowMessage>,
IRecipient<HideWindowMessage>,
@@ -82,7 +84,6 @@ public sealed partial class MainWindow : Window,
this.SetIcon();
AppWindow.Title = RS_.GetString("AppName");
AppWindow.Resize(new SizeInt32 { Width = 1000, Height = 620 });
PositionCentered();
SetAcrylic();
@@ -232,6 +233,16 @@ public sealed partial class MainWindow : Window,
PositionCentered(display);
PInvoke.ShowWindow(hwnd, SHOW_WINDOW_CMD.SW_SHOW);
// instead of showing the window, uncloak it from DWM
// This will make it visible to the user, without the animation or frames for
// loading XAML with composition
unsafe
{
BOOL value = false;
PInvoke.DwmSetWindowAttribute(_hwnd, DWMWINDOWATTRIBUTE.DWMWA_CLOAK, (void*)&value, (uint)sizeof(BOOL));
}
PInvoke.SetForegroundWindow(hwnd);
PInvoke.SetActiveWindow(hwnd);
}
@@ -289,7 +300,7 @@ public sealed partial class MainWindow : Window,
ShowHwnd(message.Hwnd, settings.SummonOn);
}
public void Receive(HideWindowMessage message) => PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
public void Receive(HideWindowMessage message) => HideWindow();
public void Receive(QuitMessage message) =>
@@ -297,7 +308,21 @@ public sealed partial class MainWindow : Window,
DispatcherQueue.TryEnqueue(() => Close());
public void Receive(DismissMessage message) =>
PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
HideWindow();
private void HideWindow()
{
// Hide our window
// Instead of hiding the window, cloak it from DWM
// This will make it invisible to the user, such that we can show it again
// by uncloaking it, which avoids an unnecessary "flicker in" that XAML does
unsafe
{
BOOL value = true;
PInvoke.DwmSetWindowAttribute(_hwnd, DWMWINDOWATTRIBUTE.DWMWA_CLOAK, (void*)&value, (uint)sizeof(BOOL));
}
}
internal void MainWindow_Closed(object sender, WindowEventArgs args)
{
@@ -386,7 +411,9 @@ public sealed partial class MainWindow : Window,
return;
}
PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
// This will DWM cloak our window:
HideWindow();
PowerToysTelemetry.Log.WriteEvent(new CmdPalDismissedOnLostFocus());
}
@@ -404,11 +431,6 @@ public sealed partial class MainWindow : Window,
// know till the message is being handled.
WeakReferenceMessenger.Default.Send<HotkeySummonMessage>(new(commandId, _hwnd));
#pragma warning disable SA1310 // Field names should not contain underscore
private const uint DOT_KEY = 0xBE;
private const uint WM_HOTKEY = 0x0312;
#pragma warning restore SA1310 // Field names should not contain underscore
private void UnregisterHotkeys()
{
_keyboardListener.ClearHotkeys();
@@ -479,10 +501,24 @@ public sealed partial class MainWindow : Window,
var isRootHotkey = string.IsNullOrEmpty(commandId);
PowerToysTelemetry.Log.WriteEvent(new CmdPalHotkeySummoned(isRootHotkey));
var isVisible = this.Visible;
unsafe
{
// We need to check if our window is cloaked or not. A cloaked window is still
// technically visible, because SHOW/HIDE != iconic (minimized) != cloaked
// (these are all separate states)
long attr = 0;
PInvoke.DwmGetWindowAttribute(_hwnd, DWMWINDOWATTRIBUTE.DWMWA_CLOAKED, &attr, sizeof(long));
if (attr == 1 /* DWM_CLOAKED_APP */)
{
isVisible = false;
}
}
// Note to future us: the wParam will have the index of the hotkey we registered.
// We can use that in the future to differentiate the hotkeys we've pressed
// so that we can bind hotkeys to individual commands
if (!this.Visible || !isRootHotkey)
if (!isVisible || !isRootHotkey)
{
Activate();
@@ -490,7 +526,16 @@ public sealed partial class MainWindow : Window,
}
else if (isRootHotkey)
{
PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
// If there's a debugger attached...
if (System.Diagnostics.Debugger.IsAttached)
{
// ... then manually hide our window. When debugged, we won't get the cool cloaking,
// but that's the price to pay for having the HWND not light-dismiss while we're debugging.
PInvoke.ShowWindow(_hwnd, SHOW_WINDOW_CMD.SW_HIDE);
return;
}
HideWindow();
}
}
@@ -502,7 +547,10 @@ public sealed partial class MainWindow : Window,
{
switch (uMsg)
{
case WM_HOTKEY:
// Prevent the window from maximizing when double-clicking the title bar area
case PInvoke.WM_NCLBUTTONDBLCLK:
return (LRESULT)IntPtr.Zero;
case PInvoke.WM_HOTKEY:
{
var hotkeyIndex = (int)wParam.Value;
if (hotkeyIndex < _hotkeys.Count)
@@ -518,22 +566,6 @@ public sealed partial class MainWindow : Window,
var hotkey = _hotkeys[hotkeyIndex];
HandleSummon(hotkey.CommandId);
// var isRootHotkey = string.IsNullOrEmpty(hotkey.CommandId);
// // Note to future us: the wParam will have the index of the hotkey we registered.
// // We can use that in the future to differentiate the hotkeys we've pressed
// // so that we can bind hotkeys to individual commands
// if (!this.Visible || !isRootHotkey)
// {
// Activate();
// Summon(hotkey.CommandId);
// }
// else if (isRootHotkey)
// {
// PInvoke.ShowWindow(hwnd, SHOW_WINDOW_CMD.SW_HIDE);
// }
}
return (LRESULT)IntPtr.Zero;
@@ -592,7 +624,7 @@ public sealed partial class MainWindow : Window,
_largeIcon = GetAppIconHandle();
_trayIconData = new NOTIFYICONDATAW()
{
cbSize = (uint)Marshal.SizeOf(typeof(NOTIFYICONDATAW)),
cbSize = (uint)Marshal.SizeOf<NOTIFYICONDATAW>(),
hWnd = _hwnd,
uID = MY_NOTIFY_ID,
uFlags = NOTIFY_ICON_DATA_FLAGS.NIF_MESSAGE | NOTIFY_ICON_DATA_FLAGS.NIF_ICON | NOTIFY_ICON_DATA_FLAGS.NIF_TIP,
@@ -629,7 +661,10 @@ public sealed partial class MainWindow : Window,
private DestroyIconSafeHandle GetAppIconHandle()
{
var exePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
// var exePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
// todo: use the path to the current assembly
var exePath = Path.Combine(AppContext.BaseDirectory, "Microsoft.CmdPal.UI.exe");
DestroyIconSafeHandle largeIcon;
PInvoke.ExtractIconEx(exePath, 0, out largeIcon, out _, 1);
return largeIcon;

View File

@@ -23,6 +23,16 @@
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
<PropertyGroup>
<SelfContained>true</SelfContained>
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
<PublishTrimmed>true</PublishTrimmed>
<PublishSingleFile>true</PublishSingleFile>
<DisableRuntimeMarshalling>false</DisableRuntimeMarshalling>
<PublishAot>true</PublishAot>
<EnableMsixTooling>true</EnableMsixTooling>
</PropertyGroup>
<PropertyGroup>
<GenerateAppxPackageOnBuild>true</GenerateAppxPackageOnBuild>
</PropertyGroup>
@@ -61,12 +71,11 @@
<PackageReference Include="CommunityToolkit.WinUI.Converters" />
<PackageReference Include="CommunityToolkit.WinUI.Animations" />
<PackageReference Include="CommunityToolkit.WinUI.Extensions" />
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.Markdown" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
<PackageReference Include="Microsoft.WindowsAppSDK" />
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" />
<PackageReference Include="WinUIEx" />
<PackageReference Include="Microsoft.Windows.CsWin32">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
@@ -80,9 +89,6 @@
<PackageReference Include="System.Text.Json" />
<!-- LOAD BEARING: GeneratePathProperty=true on BOTH the AC dependencies. Don't forget the AdaptiveCardsWorkaround below -->
<PackageReference Include="AdaptiveCards.ObjectModel.WinUI3" GeneratePathProperty="true" />
<PackageReference Include="AdaptiveCards.Rendering.WinUI3" GeneratePathProperty="True" />
<PackageReference Include="AdaptiveCards.Templating" />
<PackageReference Include="System.Text.RegularExpressions" />
</ItemGroup>
@@ -97,26 +103,12 @@
<ItemGroup>
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.System\Microsoft.CmdPal.Ext.System.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.WebSearch\Microsoft.CmdPal.Ext.WebSearch.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Indexer\Microsoft.CmdPal.Ext.Indexer.csproj" />
<ProjectReference Include="..\Microsoft.CmdPal.Common\Microsoft.CmdPal.Common.csproj" />
<ProjectReference Include="..\Microsoft.CmdPal.UI.ViewModels\Microsoft.CmdPal.UI.ViewModels.csproj" />
<ProjectReference Include="..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Apps\Microsoft.CmdPal.Ext.Apps.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Bookmark\Microsoft.CmdPal.Ext.Bookmarks.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Calc\Microsoft.CmdPal.Ext.Calc.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.ClipboardHistory\Microsoft.CmdPal.Ext.ClipboardHistory.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Registry\Microsoft.CmdPal.Ext.Registry.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Shell\Microsoft.CmdPal.Ext.Shell.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.TimeDate\Microsoft.CmdPal.Ext.TimeDate.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.WindowsServices\Microsoft.CmdPal.Ext.WindowsServices.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.WindowsSettings\Microsoft.CmdPal.Ext.WindowsSettings.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.WindowsTerminal\Microsoft.CmdPal.Ext.WindowsTerminal.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.WindowWalker\Microsoft.CmdPal.Ext.WindowWalker.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.WinGet\Microsoft.CmdPal.Ext.WinGet.csproj" />
<ProjectReference Include="..\Microsoft.Terminal.UI\Microsoft.Terminal.UI.vcxproj">
<ReferenceOutputAssembly>True</ReferenceOutputAssembly>
@@ -168,13 +160,6 @@
<!-- <AdaptiveCardsWorkaround> -->
<!-- Workaround for Adaptive Cards not supporting correct RIDs when using .NET 8.
Don't forget GeneratePathProperty on the AdaptiveCards PackageReference's above -->
<PropertyGroup>
<AdaptiveCardsNative>runtimes\win10-$(Platform)\native</AdaptiveCardsNative>
</PropertyGroup>
<ItemGroup>
<Content Include="$(PkgAdaptiveCards_ObjectModel_WinUI3)\$(AdaptiveCardsNative)\AdaptiveCards.ObjectModel.WinUI3.dll" Link="AdaptiveCards.ObjectModel.WinUI3.dll" CopyToOutputDirectory="PreserveNewest" />
<Content Include="$(PkgAdaptiveCards_Rendering_WinUI3)\$(AdaptiveCardsNative)\AdaptiveCards.Rendering.WinUI3.dll" Link="AdaptiveCards.Rendering.WinUI3.dll" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup>
<Content Update="..\Microsoft.CmdPal.UI.ViewModels\Assets\template.zip">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

View File

@@ -1,7 +1,6 @@
GetPhysicallyInstalledSystemMemory
GlobalMemoryStatusEx
GetSystemInfo
CoCreateInstance
GetForegroundWindow
SetForegroundWindow
GetWindowRect
@@ -21,18 +20,21 @@ SetActiveWindow
MonitorFromWindow
GetMonitorInfo
GetDpiForMonitor
SHCreateStreamOnFileEx
CoAllowSetForegroundWindow
SHCreateStreamOnFileEx
SHLoadIndirectString
WM_HOTKEY
WM_NCLBUTTONDBLCLK
Shell_NotifyIcon
LoadIcon
WM_USER
WM_WINDOWPOSCHANGING
RegisterWindowMessageW
GetModuleHandleW
ExtractIconEx
WM_RBUTTONUP
WM_LBUTTONUP
WM_LBUTTONDBLCLK
DwmGetWindowAttribute
DwmSetWindowAttribute
DWM_CLOAKED_APP

View File

@@ -10,7 +10,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:help="using:Microsoft.CmdPal.UI.Helpers"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="using:CommunityToolkit.WinUI.UI.Controls"
xmlns:ui="using:CommunityToolkit.WinUI"
xmlns:viewModels="using:Microsoft.CmdPal.UI.ViewModels"
Background="Transparent"
@@ -98,13 +97,6 @@
Visibility="{x:Bind HasTags, Mode=OneWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel
x:Name="TagsWrapPanel"
MinWidth="0"
Padding="0"
HorizontalSpacing="4"
Orientation="Horizontal"
VerticalSpacing="4" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
@@ -374,16 +366,6 @@
TextWrapping="WrapWholeWords"
Visibility="{x:Bind ViewModel.Details.Title, Converter={StaticResource StringNotEmptyToVisibilityConverter}, Mode=OneWay}" />
<toolkit:MarkdownTextBlock
Grid.Row="2"
Margin="0,12,0,24"
Background="Transparent"
Header3FontSize="12"
Header3FontWeight="Normal"
Header3Foreground="{ThemeResource TextFillColorSecondaryBrush}"
IsTextSelectionEnabled="True"
Text="{x:Bind ViewModel.Details.Body, Mode=OneWay}" />
<ItemsRepeater
Grid.Row="3"
ItemTemplate="{StaticResource DetailsDataTemplateSelector}"

View File

@@ -418,9 +418,6 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
{
_ = DispatcherQueue.TryEnqueue(() =>
{
// Also hide our details pane about here, if we had one
HideDetails();
if (_settingsWindow == null)
{
_settingsWindow = new SettingsWindow();

View File

@@ -13,7 +13,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">False</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">True</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>
</PropertyGroup>
</Project>

View File

@@ -13,7 +13,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">False</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">True</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>
</PropertyGroup>
</Project>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<Window
<winuiex:WindowEx
x:Class="Microsoft.CmdPal.UI.Settings.SettingsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -7,13 +7,18 @@
xmlns:local="using:Microsoft.CmdPal.UI.Settings"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
xmlns:winuiex="using:WinUIEx"
Title="SettingsWindow"
Width="1280"
Height="720"
MinWidth="480"
MinHeight="480"
Activated="Window_Activated"
Closed="Window_Closed"
mc:Ignorable="d">
<Window.SystemBackdrop>
<winuiex:WindowEx.SystemBackdrop>
<MicaBackdrop />
</Window.SystemBackdrop>
</winuiex:WindowEx.SystemBackdrop>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
@@ -37,10 +42,10 @@
Height="16"
Source="ms-appx:///Assets/icon.svg" />
<TextBlock
x:Uid="CmdPalSettingsHeader"
Margin="12,0,0,0"
VerticalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="Command Palette Settings" />
Style="{StaticResource CaptionTextBlockStyle}" />
</StackPanel>
<NavigationView
x:Name="NavView"
@@ -100,4 +105,4 @@
</Grid>
</NavigationView>
</Grid>
</Window>
</winuiex:WindowEx>

View File

@@ -11,11 +11,12 @@ using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Windows.Graphics;
using WinUIEx;
using RS_ = Microsoft.CmdPal.UI.Helpers.ResourceLoaderInstance;
namespace Microsoft.CmdPal.UI.Settings;
public sealed partial class SettingsWindow : Window,
public sealed partial class SettingsWindow : WindowEx,
IRecipient<NavigateToExtensionSettingsMessage>,
IRecipient<QuitMessage>
{
@@ -70,7 +71,6 @@ public sealed partial class SettingsWindow : Window,
private void PositionCentered()
{
AppWindow.Resize(new SizeInt32 { Width = 1280, Height = 720 });
var displayArea = DisplayArea.GetFromWindowId(AppWindow.Id, DisplayAreaFallback.Nearest);
if (displayArea is not null)
{

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<Window
<winuiex:WindowEx
x:Class="Microsoft.CmdPal.UI.ToastWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -7,17 +7,18 @@
xmlns:local="using:Microsoft.CmdPal.UI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
xmlns:winuiex="using:WinUIEx"
Title="Command Palette Toast"
mc:Ignorable="d">
<Window.SystemBackdrop>
<winuiex:WindowEx.SystemBackdrop>
<DesktopAcrylicBackdrop />
</Window.SystemBackdrop>
</winuiex:WindowEx.SystemBackdrop>
<Grid x:Name="ToastGrid">
<!-- This padding is used to calculate the dimensions of the ToastWindow -->
<TextBlock
x:Name="ToastText"
Padding="16,16,36,24"
Padding="12,12,24,20"
Text="{x:Bind ViewModel.ToastMessage, Mode=OneWay}"
TextAlignment="Center" />
</Grid>
</Window>
</winuiex:WindowEx>

View File

@@ -17,11 +17,12 @@ using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Gdi;
using Windows.Win32.UI.HiDpi;
using Windows.Win32.UI.WindowsAndMessaging;
using WinUIEx;
using RS_ = Microsoft.CmdPal.UI.Helpers.ResourceLoaderInstance;
namespace Microsoft.CmdPal.UI;
public sealed partial class ToastWindow : Window,
public sealed partial class ToastWindow : WindowEx,
IRecipient<QuitMessage>
{
private readonly HWND _hwnd;
@@ -64,19 +65,7 @@ public sealed partial class ToastWindow : Window,
private void PositionCentered()
{
var intSize = new SizeInt32
{
Width = Convert.ToInt32(ToastText.ActualWidth),
Height = Convert.ToInt32(ToastText.ActualHeight),
};
var scaleAdjustment = GetScaleFactor(_hwnd);
var scaled = new SizeInt32
{
Width = (int)Math.Round(intSize.Width * scaleAdjustment),
Height = (int)Math.Round(intSize.Height * scaleAdjustment),
};
AppWindow.Resize(scaled);
this.SetWindowSize(ToastText.ActualWidth, ToastText.ActualHeight);
var displayArea = DisplayArea.GetFromWindowId(AppWindow.Id, DisplayAreaFallback.Nearest);
if (displayArea is not null)
@@ -86,7 +75,7 @@ public sealed partial class ToastWindow : Window,
var monitorHeight = displayArea.WorkArea.Height;
var windowHeight = AppWindow.Size.Height;
centeredPosition.Y = monitorHeight - (windowHeight * 2);
centeredPosition.Y = monitorHeight - (windowHeight + 8); // Align with other shell toasts, like the volume indicator.
AppWindow.Move(centeredPosition);
}
}

View File

@@ -9,7 +9,7 @@ By default, CmdPal is bound to <kbd>Win+Alt+Space</kbd>.
The fastest way to get started is just to run the "Create extension" command in the palette itself. That'll prompt you for a project name and a Display Name, and where you want to place your project. Then just open the `sln` it produces. You should be ready to go 🙂.
The official API documentation can be found [on this docs site](TODO! Add docs link when we have one)
The official API documentation can be found [on this docs site](https://learn.microsoft.com/windows/powertoys/command-palette/extensibility-overview).
We've also got samples, so that you can see how the APIs in-action.

View File

@@ -12,7 +12,7 @@ using Microsoft.CmdPal.Ext.Apps.Utils;
namespace Microsoft.CmdPal.Ext.Apps;
public sealed class AppCache : IDisposable
public sealed partial class AppCache : IDisposable
{
private Win32ProgramFileSystemWatchers _win32ProgramRepositoryHelper;

View File

@@ -1,11 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\Common.Dotnet.CsWinRT.props" />
<PropertyGroup>
<Import Project="..\..\..\..\Common.Dotnet.AotCompatibility.props" />
<PropertyGroup>
<RootNamespace>Microsoft.CmdPal.Ext.Apps</RootNamespace>
<Nullable>enable</Nullable>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\WinUI3Apps\CmdPal</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
@@ -49,4 +52,8 @@
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<PropertyGroup>
<DisableRuntimeMarshalling>true</DisableRuntimeMarshalling>
</PropertyGroup>
</Project>

View File

@@ -1,7 +1,6 @@
GetPhysicallyInstalledSystemMemory
GlobalMemoryStatusEx
GetSystemInfo
CoCreateInstance
SetForegroundWindow
IsIconic
RegisterHotKey
@@ -13,7 +12,6 @@ SetFocus
SetActiveWindow
MonitorFromWindow
GetMonitorInfo
SHCreateStreamOnFileEx
CoAllowSetForegroundWindow
SHCreateStreamOnFileEx
SHLoadIndirectString
SHLoadIndirectString
IStream

View File

@@ -195,7 +195,7 @@ public static class ReparsePoint
public AppExecutionAliasReparseTagBufferLayoutVersion Version;
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[LibraryImport("kernel32.dll")]
private static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
@@ -206,7 +206,7 @@ public static class ReparsePoint
out int pBytesReturned,
IntPtr lpOverlapped);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[LibraryImport("kernel32.dll")]
private static extern IntPtr CreateFile(
string lpFileName,
FileAccessType dwDesiredAccess,
@@ -319,7 +319,7 @@ public static class ReparsePoint
public static AppExecutionAliasMetadata FromPersistedRepresentationIntPtr(IntPtr reparseDataBufferPtr, AppExecutionAliasReparseTagBufferLayoutVersion version)
{
var dataOffset = Marshal.SizeOf(typeof(AppExecutionAliasReparseTagHeader));
var dataOffset = Marshal.SizeOf<AppExecutionAliasReparseTagHeader>();
var dataBufferPtr = reparseDataBufferPtr + dataOffset;
string? packageFullName = null;

View File

@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using System.Runtime.InteropServices;
using System.Xml.Linq;
using Microsoft.CmdPal.Ext.Apps.Utils;
using Windows.Win32;
@@ -65,11 +66,18 @@ public partial class UWP
const uint noAttribute = 0x80;
var access = (uint)STGM.READ;
var hResult = PInvoke.SHCreateStreamOnFileEx(path, access, noAttribute, false, null, out IStream stream);
var hResult = Native.SHCreateStreamOnFileEx(path, access, noAttribute, false, IntPtr.Zero, out var streamPtr);
// S_OK
if (hResult == 0)
{
// create IStream from streamPtr
var stream = Marshal.GetTypedObjectForIUnknown(streamPtr, typeof(IStream)) as IStream;
if (stream == null)
{
return;
}
Apps = AppxPackageHelper.GetAppsFromManifest(stream).Select(appInManifest => new UWPApplication(appInManifest, this)).Where(a =>
{
var valid =

View File

@@ -197,9 +197,10 @@ public class UWPApplication : IProgram
parsedFallback = prefix + "///" + key;
}
var outBuffer = new StringBuilder(128);
var outBuffer = new char[1024];
var source = $"@{{{packageFullName}? {parsed}}}";
var capacity = (uint)outBuffer.Capacity;
var capacity = (uint)outBuffer.Length;
var hResult = SHLoadIndirectString(source, outBuffer, capacity, IntPtr.Zero);
if (hResult != HRESULT.S_OK)
{

View File

@@ -374,15 +374,17 @@ public class Win32Program : IProgram
return program;
}
catch (System.IO.FileLoadException)
catch (System.IO.FileLoadException ex)
{
ExtensionHost.LogMessage(ex.ToString());
return InvalidProgram;
}
// Only do a catch all in production. This is so make developer aware of any unhandled exception and add the exception handling in.
// Error caused likely due to trying to get the description of the program
catch (Exception)
catch (Exception ex)
{
ExtensionHost.LogMessage(ex.ToString());
return InvalidProgram;
}
}

View File

@@ -8,7 +8,7 @@ using System.IO;
namespace Microsoft.CmdPal.Ext.Apps.Storage;
// File System Watcher Wrapper class which implements the IFileSystemWatcherWrapper interface
public sealed class FileSystemWatcherWrapper : FileSystemWatcher, IFileSystemWatcherWrapper
public sealed partial class FileSystemWatcherWrapper : FileSystemWatcher, IFileSystemWatcherWrapper
{
public FileSystemWatcherWrapper()
{

View File

@@ -15,7 +15,7 @@ namespace Microsoft.CmdPal.Ext.Apps.Storage;
/// A repository for storing packaged applications such as UWP apps or appx packaged desktop apps.
/// This repository will also monitor for changes to the PackageCatalog and update the repository accordingly
/// </summary>
internal sealed class PackageRepository : ListRepository<UWPApplication>, IProgramRepository
internal sealed partial class PackageRepository : ListRepository<UWPApplication>, IProgramRepository
{
private readonly IPackageCatalog _packageCatalog;

View File

@@ -9,7 +9,7 @@ using System.Linq;
namespace Microsoft.CmdPal.Ext.Apps.Storage;
internal sealed class Win32ProgramFileSystemWatchers : IDisposable
internal sealed partial class Win32ProgramFileSystemWatchers : IDisposable
{
public string[] PathsToWatch { get; set; }

View File

@@ -14,7 +14,7 @@ using Win32Program = Microsoft.CmdPal.Ext.Apps.Programs.Win32Program;
namespace Microsoft.CmdPal.Ext.Apps.Storage;
internal sealed class Win32ProgramRepository : ListRepository<Programs.Win32Program>, IProgramRepository
internal sealed partial class Win32ProgramRepository : ListRepository<Programs.Win32Program>, IProgramRepository
{
private static readonly IFileSystem FileSystem = new FileSystem();
private static readonly IPath Path = FileSystem.Path;

View File

@@ -5,24 +5,28 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Text;
using System.Runtime.InteropServices.Marshalling;
using Dia2Lib;
namespace Microsoft.CmdPal.Ext.Apps.Utils;
[SuppressMessage("Interoperability", "CA1401:P/Invokes should not be visible", Justification = "We want plugins to share this NativeMethods class, instead of each one creating its own.")]
public sealed class Native
public sealed partial class Native
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, int cchOutBuf, nint ppvReserved);
[LibraryImport("shell32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
public static partial int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string path, nint pbc, ref Guid riid, [MarshalUsing(typeof(IShellItemMarshallerOut))] out IShellItem? shellItem);
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string path, nint pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem);
[LibraryImport("shlwapi.dll", StringMarshalling = StringMarshalling.Utf16)]
public static partial HRESULT SHLoadIndirectString(string pszSource, Span<char> pszOutBuf, uint cchOutBuf, nint ppvReserved);
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern HRESULT SHCreateStreamOnFileEx(string fileName, STGM grfMode, uint attributes, bool create, System.Runtime.InteropServices.ComTypes.IStream reserved, out System.Runtime.InteropServices.ComTypes.IStream stream);
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern HRESULT SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, uint cchOutBuf, nint ppvReserved);
[LibraryImport("shlwapi.dll", StringMarshalling = StringMarshalling.Utf16)]
public static partial int SHCreateStreamOnFileEx(
string pszFile,
uint grfMode,
uint dwAttributes,
[MarshalAs(UnmanagedType.Bool)]bool fCreate,
IntPtr pstmTemplate,
out IntPtr ppstm);
public enum HRESULT : uint
{
@@ -129,14 +133,14 @@ public sealed class Native
public interface IShellItem
{
void BindToHandler(
nint pbc,
[MarshalAs(UnmanagedType.LPStruct)] Guid bhid,
[MarshalAs(UnmanagedType.LPStruct)] Guid riid,
out nint ppv);
IntPtr pbc,
ref Guid bhid,
ref Guid riid,
out IntPtr ppv);
void GetParent(out IShellItem ppsi);
void GetDisplayName(SIGDN sigdnName, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName);
void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
@@ -154,4 +158,24 @@ public sealed class Native
READWRITE = 0x00000002L,
CREATE = 0x00001000L,
}
[CustomMarshaller(typeof(IShellItem), MarshalMode.ManagedToUnmanagedOut, typeof(IShellItemMarshallerOut))]
public static partial class IShellItemMarshallerOut
{
public static IShellItem? ConvertToManaged(IntPtr unmanaged)
{
if (unmanaged == IntPtr.Zero)
{
return null;
}
var obj = Marshal.GetObjectForIUnknown(unmanaged);
return (IShellItem)obj;
}
public static void Free(IntPtr managed)
{
Marshal.FreeCoTaskMem(managed);
}
}
}

View File

@@ -4,6 +4,7 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Runtime.InteropServices;
using static Microsoft.CmdPal.Ext.Apps.Utils.Native;
namespace Microsoft.CmdPal.Ext.Apps.Utils;
@@ -40,7 +41,21 @@ public class ShellLocalization
return string.Empty;
}
shellItem.GetDisplayName(SIGDN.NORMALDISPLAY, out var filename);
if (shellItem == null)
{
return string.Empty;
}
shellItem.GetDisplayName(SIGDN.NORMALDISPLAY, out var filenamePtr);
// get filename from ptr
var filename = Marshal.PtrToStringUni(filenamePtr);
Marshal.FreeCoTaskMem(filenamePtr);
if (filename == null)
{
return string.Empty;
}
_ = _localizationCache.TryAdd(lowerInvariantPath, filename);

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Indexer.Data;
@@ -13,6 +14,7 @@ using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.UI.Shell;
using Windows.Win32.UI.WindowsAndMessaging;
using static Microsoft.CmdPal.Ext.Indexer.Native.NativeMethods;
namespace Microsoft.CmdPal.Ext.Indexer.Commands;
@@ -30,16 +32,17 @@ internal sealed partial class OpenPropertiesCommand : InvokableCommand
var filenamePCWSTR = new PCWSTR((char*)filenamePtr);
var propertiesPCWSTR = new PCWSTR((char*)propertiesPtr);
var info = new SHELLEXECUTEINFOW
var info = new NativeMethods.SHELLEXECUTEINFOW
{
cbSize = (uint)Marshal.SizeOf<SHELLEXECUTEINFOW>(),
lpVerb = propertiesPCWSTR,
lpFile = filenamePCWSTR,
cbSize = Unsafe.SizeOf<NativeMethods.SHELLEXECUTEINFOW>(),
lpVerb = propertiesPCWSTR.ToString(),
lpFile = filenamePCWSTR.ToString(),
nShow = (int)SHOW_WINDOW_CMD.SW_SHOW,
fMask = NativeHelpers.SEEMASKINVOKEIDLIST,
};
return PInvoke.ShellExecuteEx(ref info);
return NativeMethods.ShellExecuteEx(ref info);
}
finally
{

View File

@@ -2,6 +2,7 @@
// 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.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Native;
@@ -28,16 +29,17 @@ internal sealed partial class OpenWithCommand : InvokableCommand
var filenamePCWSTR = new PCWSTR((char*)filenamePtr);
var verbPCWSTR = new PCWSTR((char*)verbPtr);
var info = new SHELLEXECUTEINFOW
var info = new NativeMethods.SHELLEXECUTEINFOW
{
cbSize = (uint)Marshal.SizeOf<SHELLEXECUTEINFOW>(),
lpVerb = verbPCWSTR,
lpFile = filenamePCWSTR,
cbSize = Unsafe.SizeOf<NativeMethods.SHELLEXECUTEINFOW>(),
lpVerb = verbPCWSTR.ToString(),
lpFile = filenamePCWSTR.ToString(),
nShow = (int)SHOW_WINDOW_CMD.SW_SHOWNORMAL,
fMask = NativeHelpers.SEEMASKINVOKEIDLIST,
};
return PInvoke.ShellExecuteEx(ref info);
return NativeMethods.ShellExecuteEx(ref info);
}
finally
{

View File

@@ -2,7 +2,10 @@
// 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.Globalization;
using System.IO;
using System.Text;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
@@ -10,8 +13,14 @@ using Windows.Storage.Streams;
namespace Microsoft.CmdPal.Ext.Indexer;
internal sealed partial class FallbackOpenFileItem : FallbackCommandItem
internal sealed partial class FallbackOpenFileItem : FallbackCommandItem, System.IDisposable
{
private readonly CompositeFormat fallbackItemSearchPageTitleCompositeFormat = CompositeFormat.Parse(Resources.Indexer_fallback_searchPage_title);
private readonly SearchEngine _searchEngine = new();
private uint _queryCookie = 10;
public FallbackOpenFileItem()
: base(new NoOpCommand(), Resources.Indexer_Find_Path_fallback_display_title)
{
@@ -21,8 +30,20 @@ internal sealed partial class FallbackOpenFileItem : FallbackCommandItem
public override void UpdateQuery(string query)
{
if (string.IsNullOrWhiteSpace(query))
{
Command = new NoOpCommand();
Title = string.Empty;
Subtitle = string.Empty;
Icon = null;
MoreCommands = null;
return;
}
if (Path.Exists(query))
{
// Exit 1: The query is a direct path to a file. Great! Return it.
var item = new IndexerItem() { FullPath = query, FileName = Path.GetFileName(query) };
var listItemForUs = new IndexerListItem(item, IncludeBrowseCommand.AsDefault);
Command = listItemForUs.Command;
@@ -43,12 +64,65 @@ internal sealed partial class FallbackOpenFileItem : FallbackCommandItem
catch
{
}
return;
}
else
{
Title = string.Empty;
Subtitle = string.Empty;
Command = new NoOpCommand();
_queryCookie++;
try
{
_searchEngine.Query(query, _queryCookie);
var results = _searchEngine.FetchItems(0, 20, _queryCookie, out var _);
if (results.Count == 0 || ((results[0] as IndexerListItem) == null))
{
// Exit 2: We searched for the file, and found nothing. Oh well.
// Hide ourselves.
Title = string.Empty;
Subtitle = string.Empty;
Command = new NoOpCommand();
return;
}
if (results.Count == 1)
{
// Exit 3: We searched for the file, and found exactly one thing. Awesome!
// Return it.
Title = results[0].Title;
Subtitle = results[0].Subtitle;
Icon = results[0].Icon;
Command = results[0].Command;
MoreCommands = results[0].MoreCommands;
return;
}
// Exit 4: We found more than one result. Make our command take
// us to the file search page, prepopulated with this search.
var indexerPage = new IndexerPage(query, _searchEngine, _queryCookie, results);
Title = string.Format(CultureInfo.CurrentCulture, fallbackItemSearchPageTitleCompositeFormat, query);
Icon = Icons.FileExplorer;
Subtitle = Resources.Indexer_Subtitle;
Command = indexerPage;
return;
}
catch
{
Title = string.Empty;
Subtitle = string.Empty;
Icon = null;
Command = new NoOpCommand();
MoreCommands = null;
}
}
}
public void Dispose()
{
_searchEngine.Dispose();
GC.SuppressFinalize(this);
}
}

View File

@@ -3,9 +3,9 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
using ManagedCommon;
using Windows.Win32;
using Windows.Win32.System.Com;
using Microsoft.CmdPal.Ext.Indexer.Native;
using Windows.Win32.System.Search;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer;
@@ -28,13 +28,17 @@ internal static class DataSourceManager
private static bool InitializeDataSource()
{
var hr = PInvoke.CoCreateInstance(CLSIDCollatorDataSource, null, CLSCTX.CLSCTX_INPROC_SERVER, typeof(IDBInitialize).GUID, out var dataSourceObj);
uint clsctxInProcServer = 0x00000001;
var hr = NativeMethods.CoCreateInstance(CLSIDCollatorDataSource, IntPtr.Zero, clsctxInProcServer, typeof(IDBInitialize).GUID, out var dataSourceObjPtr);
if (hr != 0)
{
Logger.LogError("CoCreateInstance failed: " + hr);
return false;
}
// create datasource object from ptr
var dataSourceObj = Marshal.GetObjectForIUnknown(dataSourceObjPtr);
if (dataSourceObj == null)
{
Logger.LogError("CoCreateInstance failed: dataSourceObj is null");

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices;
using Microsoft.CmdPal.Ext.Indexer.Native;
using Windows.Win32.Storage.IndexServer;
using Windows.Win32.System.Com.StructuredStorage;
@@ -16,6 +17,6 @@ internal struct DBPROP
public uint dwOptions;
public uint dwStatus;
public DBID colid;
public PROPVARIANT vValue;
public NativeHelpers.PROPVARIANT vValue;
#pragma warning restore SA1307 // Accessible fields should begin with upper-case letter
}

View File

@@ -4,13 +4,14 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.OleDB;
[ComImport]
[Guid("0c733a7c-2a1c-11ce-ade5-00aa0044773d")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IRowset
[GeneratedComInterface]
public partial interface IRowset
{
[PreserveSig]
int AddRefRows(

View File

@@ -4,29 +4,30 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.OleDB;
[ComImport]
[Guid("0C733A55-2A1C-11CE-ADE5-00AA0044773D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IRowsetInfo
[GeneratedComInterface]
public partial interface IRowsetInfo
{
[PreserveSig]
int GetProperties(
uint cPropertyIDSets,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] DBPROPIDSET[] rgPropertyIDSets,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] DBPROPIDSET[] rgPropertyIDSets,
out ulong pcPropertySets,
out IntPtr prgPropertySets);
[PreserveSig]
int GetReferencedRowset(
uint iOrdinal,
[In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppReferencedRowset);
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out object ppReferencedRowset);
[PreserveSig]
int GetSpecification(
[In] ref Guid riid,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppSpecification);
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out object ppSpecification);
}

View File

@@ -5,15 +5,14 @@
using System;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
using System.Threading;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Indexer.Indexer.OleDB;
using Microsoft.CmdPal.Ext.Indexer.Indexer.Utils;
using Microsoft.CmdPal.Ext.Indexer.Native;
using Windows.Win32;
using Windows.Win32.System.Com;
using Windows.Win32.System.Search;
using Windows.Win32.UI.Shell.PropertiesSystem;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer;
@@ -122,7 +121,7 @@ internal sealed partial class SearchQuery : IDisposable
{
if (reuseRowset != null)
{
Marshal.ReleaseComObject(reuseRowset);
// Marshal.ReleaseComObject(reuseRowset);
}
// We have a previous rowset, this means the user is typing and we should store this
@@ -152,9 +151,16 @@ internal sealed partial class SearchQuery : IDisposable
try
{
getRow.GetRowFromHROW(null, rowHandle, typeof(IPropertyStore).GUID, out propertyStorePtr);
getRow.GetRowFromHROW(null, rowHandle, NativeMethods.PropertyStoreGUID, out propertyStorePtr);
var propertyStore = (IPropertyStore)propertyStorePtr;
// get IpropertyStore from propertyStorePtr
if (propertyStorePtr == null)
{
Logger.LogError("Failed to get property store pointer");
return false;
}
var propertyStore = (NativeMethods.IPropertyStore)propertyStorePtr;
if (propertyStore == null)
{
Logger.LogError("Failed to get IPropertyStore interface");
@@ -270,7 +276,7 @@ internal sealed partial class SearchQuery : IDisposable
{
if (reuseRowset != null)
{
Marshal.ReleaseComObject(reuseRowset);
// Marshal.ReleaseComObject(reuseRowset);
}
reuseRowset = rowset;
@@ -344,46 +350,52 @@ internal sealed partial class SearchQuery : IDisposable
var rowsetPtr = IntPtr.Zero;
var rowsetInfoPtr = IntPtr.Zero;
try
unsafe
{
// Get the IUnknown pointer for the IRowset object
rowsetPtr = Marshal.GetIUnknownForObject(rowset);
// Query for IRowsetInfo interface
var rowsetInfoGuid = typeof(IRowsetInfo).GUID;
var res = Marshal.QueryInterface(rowsetPtr, in rowsetInfoGuid, out rowsetInfoPtr);
if (res != 0)
try
{
Logger.LogError($"Error getting IRowsetInfo interface: {res}");
IRowsetInfo rowsetInfo = (IRowsetInfo)rowset;
/*
// Get the IUnknown pointer for the IRowset object
rowsetPtr = Marshal.GetIUnknownForObject(rowset);
// Query for IRowsetInfo interface
var rowsetInfoGuid = typeof(IRowsetInfo).GUID;
var res = Marshal.QueryInterface(rowsetPtr, in rowsetInfoGuid, out rowsetInfoPtr);
if (res != 0)
{
Logger.LogError($"Error getting IRowsetInfo interface: {res}");
return null;
}
// Marshal the interface pointer to the actual IRowsetInfo object
var rowsetInfo = (IRowsetInfo)Marshal.GetObjectForIUnknown(rowsetInfoPtr);*/
return rowsetInfo;
}
catch (Exception ex)
{
Logger.LogError($"Exception occurred while getting IRowsetInfo. ", ex);
return null;
}
// Marshal the interface pointer to the actual IRowsetInfo object
var rowsetInfo = (IRowsetInfo)Marshal.GetObjectForIUnknown(rowsetInfoPtr);
return rowsetInfo;
}
catch (Exception ex)
{
Logger.LogError($"Exception occurred while getting IRowsetInfo. ", ex);
return null;
}
finally
{
// Release the IRowsetInfo pointer if it was obtained
if (rowsetInfoPtr != IntPtr.Zero)
finally
{
Marshal.Release(rowsetInfoPtr); // Release the IRowsetInfo pointer
}
// Release the IRowsetInfo pointer if it was obtained
if (rowsetInfoPtr != IntPtr.Zero)
{
Marshal.Release(rowsetInfoPtr); // Release the IRowsetInfo pointer
}
// Release the IUnknown pointer for the IRowset object
if (rowsetPtr != IntPtr.Zero)
{
Marshal.Release(rowsetPtr);
// Release the IUnknown pointer for the IRowset object
if (rowsetPtr != IntPtr.Zero)
{
Marshal.Release(rowsetPtr);
}
}
}
}
private DBPROP? GetPropset(IRowsetInfo rowsetInfo)
private unsafe DBPROP? GetPropset(IRowsetInfo rowsetInfo)
{
var prgPropSetsPtr = IntPtr.Zero;
@@ -404,14 +416,14 @@ internal sealed partial class SearchQuery : IDisposable
}
var firstPropSetPtr = new IntPtr(prgPropSetsPtr.ToInt64());
var propSet = Marshal.PtrToStructure<DBPROPSET>(firstPropSetPtr);
var propSet = *(DBPROPSET*)firstPropSetPtr;
if (propSet.cProperties == 0 || propSet.rgProperties == IntPtr.Zero)
{
return null;
}
var propPtr = new IntPtr(propSet.rgProperties.ToInt64());
var prop = Marshal.PtrToStructure<DBPROP>(propPtr);
var prop = *(DBPROP*)propPtr;
return prop;
}
catch (Exception ex)
@@ -443,9 +455,9 @@ internal sealed partial class SearchQuery : IDisposable
return 0;
}
if (prop?.vValue.Anonymous.Anonymous.vt == VARENUM.VT_UI4)
if (prop?.vValue.VarType == VarEnum.VT_UI4)
{
var value = prop?.vValue.Anonymous.Anonymous.Anonymous.ulVal;
var value = prop?.vValue._ulong;
return (uint)value;
}
@@ -464,13 +476,13 @@ internal sealed partial class SearchQuery : IDisposable
if (reuseRowset != null)
{
Marshal.ReleaseComObject(reuseRowset);
// Marshal.ReleaseComObject(reuseRowset);
reuseRowset = null;
}
if (currentRowset != null)
{
Marshal.ReleaseComObject(currentRowset);
// Marshal.ReleaseComObject(currentRowset);
currentRowset = null;
}

View File

@@ -3,12 +3,10 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Indexer.Indexer.Utils;
using Microsoft.CmdPal.Ext.Indexer.Native;
using Windows.Win32.System.Com;
using Windows.Win32.System.Com.StructuredStorage;
using Windows.Win32.UI.Shell.PropertiesSystem;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer;
@@ -35,18 +33,18 @@ internal sealed class SearchResult
}
}
public static unsafe SearchResult Create(IPropertyStore propStore)
public static unsafe SearchResult Create(NativeMethods.IPropertyStore propStore)
{
try
{
var key = NativeHelpers.PropertyKeys.PKEYItemNameDisplay;
propStore.GetValue(&key, out var itemNameDisplay);
propStore.GetValue(ref key, out var itemNameDisplay);
key = NativeHelpers.PropertyKeys.PKEYItemUrl;
propStore.GetValue(&key, out var itemUrl);
propStore.GetValue(ref key, out var itemUrl);
key = NativeHelpers.PropertyKeys.PKEYKindText;
propStore.GetValue(&key, out var kindText);
propStore.GetValue(ref key, out var kindText);
var filePath = GetFilePath(ref itemUrl);
var isFolder = IsFoder(ref kindText);
@@ -67,28 +65,35 @@ internal sealed class SearchResult
}
}
private static bool IsFoder(ref PROPVARIANT kindText)
private static bool IsFoder(ref NativeHelpers.PROPVARIANT kindText)
{
var kindString = GetStringFromPropVariant(ref kindText);
return string.Equals(kindString, "Folder", StringComparison.OrdinalIgnoreCase);
}
private static string GetFilePath(ref PROPVARIANT itemUrl)
private static string GetFilePath(ref NativeHelpers.PROPVARIANT itemUrl)
{
var filePath = GetStringFromPropVariant(ref itemUrl);
filePath = UrlToFilePathConverter.Convert(filePath);
return filePath;
}
private static string GetStringFromPropVariant(ref PROPVARIANT propVariant)
private static string GetStringFromPropVariant(ref NativeHelpers.PROPVARIANT propVariant)
{
if (propVariant.Anonymous.Anonymous.vt == VARENUM.VT_LPWSTR)
if (propVariant.VarType == System.Runtime.InteropServices.VarEnum.VT_LPWSTR)
{
var pwszVal = propVariant.Anonymous.Anonymous.Anonymous.pwszVal;
if (pwszVal != null)
var pwszVal = propVariant._ptr;
if (pwszVal == IntPtr.Zero)
{
return pwszVal.ToString();
return string.Empty;
}
// convert to string
var str = Marshal.PtrToStringUni(pwszVal);
// Marshal.FreeCoTaskMem(pwszVal);
return str;
}
return string.Empty;

View File

@@ -4,15 +4,15 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[CoClass(typeof(CSearchCatalogManagerClass))]
[Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF50")]
[ComImport]
[GeneratedComInterface]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1715:Identifiers should have correct prefix", Justification = "Using original name from type lib")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1302:Interface names should begin with I", Justification = "Using original name from type lib")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Using original name from type lib")]
public interface CSearchCatalogManager : ISearchCatalogManager
public partial interface CSearchCatalogManager : ISearchCatalogManager
{
}

View File

@@ -1,131 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[ComConversionLoss]
[Guid("AAB49DD5-AD0B-40AE-B654-AE8976BF6BD2")]
[ClassInterface((short)0)]
[ComImport]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1212:Property accessors should follow order", Justification = "The order of the property accessors must match the order in which the methods were defined in the vtable")]
public class CSearchCatalogManagerClass : ISearchCatalogManager, CSearchCatalogManager
{
[DispId(1610678272)]
public virtual extern string Name
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern IntPtr GetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void SetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName, [In] ref object pValue);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void GetCatalogStatus(
out object pStatus,
out object pPausedReason);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void Reset();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void Reindex();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void ReindexMatchingURLs([MarshalAs(UnmanagedType.LPWStr), In] string pszPattern);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void ReindexSearchRoot([MarshalAs(UnmanagedType.LPWStr), In] string pszRoot);
[DispId(1610678280)]
public virtual extern uint ConnectTimeout
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678282)]
public virtual extern uint DataTimeout
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern int NumberOfItems();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void NumberOfItemsToIndex(
out int plIncrementalCount,
out int plNotificationQueue,
out int plHighPriorityQueue);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public virtual extern string URLBeingIndexed();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern uint GetURLIndexingState([MarshalAs(UnmanagedType.LPWStr), In] string psz);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
public virtual extern object GetPersistentItemsChangedSink();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void RegisterViewForNotification(
[MarshalAs(UnmanagedType.LPWStr), In] string pszView,
[MarshalAs(UnmanagedType.Interface), In] object pViewChangedSink,
out uint pdwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void GetItemsChangedSink(
[MarshalAs(UnmanagedType.Interface), In] object pISearchNotifyInlineSite,
[In] ref Guid riid,
out IntPtr ppv,
out Guid pGUIDCatalogResetSignature,
out Guid pGUIDCheckPointSignature,
out uint pdwLastCheckPointNumber);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void UnregisterViewForNotification([In] uint dwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void SetExtensionClusion([MarshalAs(UnmanagedType.LPWStr), In] string pszExtension, [In] int fExclude);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
public virtual extern object EnumerateExcludedExtensions();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
public virtual extern CSearchQueryHelper GetQueryHelper();
[DispId(1610678295)]
public virtual extern int DiacriticSensitivity
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
public virtual extern object GetCrawlScopeManager();
}

View File

@@ -4,15 +4,15 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[CoClass(typeof(CSearchManagerClass))]
[Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF69")]
[ComImport]
[GeneratedComInterface]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1715:Identifiers should have correct prefix", Justification = "Using original name from type lib")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1302:Interface names should begin with I", Justification = "Using original name from type lib")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Using original name from type lib")]
public interface CSearchManager : ISearchManager
public partial interface CSearchManager : ISearchManager
{
}

View File

@@ -1,90 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[Guid("7D096C5F-AC08-4F1F-BEB7-5C22C517CE39")]
[TypeLibType(2)]
[ClassInterface((short)0)]
[ComConversionLoss]
[ComImport]
public class CSearchManagerClass : ISearchManager, CSearchManager
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void GetIndexerVersionStr([MarshalAs(UnmanagedType.LPWStr)] out string ppszVersionString);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void GetIndexerVersion(out uint pdwMajor, out uint pdwMinor);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern IntPtr GetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void SetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName, [In] ref object pValue);
[DispId(1610678276)]
public virtual extern string ProxyName
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678277)]
public virtual extern string BypassList
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void SetProxy(
[In] object sUseProxy,
[In] int fLocalByPassProxy,
[In] uint dwPortNumber,
[MarshalAs(UnmanagedType.LPWStr), In] string pszProxyName,
[MarshalAs(UnmanagedType.LPWStr), In] string pszByPassList);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
public virtual extern CSearchCatalogManager GetCatalog([MarshalAs(UnmanagedType.LPWStr), In] string pszCatalog);
[DispId(1610678280)]
public virtual extern string UserAgent
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
}
[DispId(1610678282)]
public virtual extern object UseProxy
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678283)]
public virtual extern int LocalBypass
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678284)]
public virtual extern uint PortNumber
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
}

View File

@@ -4,15 +4,15 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF63")]
[CoClass(typeof(CSearchQueryHelperClass))]
[ComImport]
[GeneratedComInterface]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1715:Identifiers should have correct prefix", Justification = "Using original name from type lib")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1302:Interface names should begin with I", Justification = "Using original name from type lib")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Using original name from type lib")]
public interface CSearchQueryHelper : ISearchQueryHelper
public partial interface CSearchQueryHelper : ISearchQueryHelper
{
}

View File

@@ -1,134 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[ClassInterface((short)0)]
[Guid("B271E955-09E1-42E1-9B95-5994A534B613")]
[ComImport]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1212:Property accessors should follow order", Justification = "The order of the property accessors must match the order in which the methods were defined in the vtable")]
public class CSearchQueryHelperClass : ISearchQueryHelper, CSearchQueryHelper
{
[DispId(1610678272)]
public virtual extern string ConnectionString
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678273)]
public virtual extern uint QueryContentLocale
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678275)]
public virtual extern uint QueryKeywordLocale
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678277)]
public virtual extern object QueryTermExpansion
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678279)]
public virtual extern object QuerySyntax
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678281)]
public virtual extern string QueryContentProperties
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678283)]
public virtual extern string QuerySelectColumns
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678285)]
public virtual extern string QueryWhereRestrictions
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678287)]
public virtual extern string QuerySorting
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public virtual extern string GenerateSQLFromUserQuery([MarshalAs(UnmanagedType.LPWStr), In] string pszQuery);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public virtual extern void WriteProperties(
[In] int itemID,
[In] uint dwNumberOfColumns,
[In] ref object pColumns,
[In] ref object pValues,
[In] ref object pftGatherModifiedTime);
[DispId(1610678291)]
public virtual extern int QueryMaxResults
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
}

View File

@@ -5,125 +5,78 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF50")]
[ComConversionLoss]
[InterfaceType(1)]
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[GeneratedComInterface]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1212:Property accessors should follow order", Justification = "The order of the property accessors must match the order in which the methods were defined in the vtable")]
public interface ISearchCatalogManager
public partial interface ISearchCatalogManager
{
[DispId(1610678272)]
string Name
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetName();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
IntPtr GetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName);
IntPtr GetParameter([MarshalAs(UnmanagedType.LPWStr)] string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName, [In] ref object pValue);
void SetParameter([MarshalAs(UnmanagedType.LPWStr)] string pszName, [MarshalAs(UnmanagedType.Interface)] ref object pValue);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCatalogStatus(out object pStatus, out object pPausedReason);
void GetCatalogStatus([MarshalAs(UnmanagedType.Interface)] out object pStatus, [MarshalAs(UnmanagedType.Interface)] out object pPausedReason);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Reset();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Reindex();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ReindexMatchingURLs([MarshalAs(UnmanagedType.LPWStr), In] string pszPattern);
void ReindexMatchingURLs([MarshalAs(UnmanagedType.LPWStr)] string pszPattern);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ReindexSearchRoot([MarshalAs(UnmanagedType.LPWStr), In] string pszRoot);
void ReindexSearchRoot([MarshalAs(UnmanagedType.LPWStr)] string pszRoot);
[DispId(1610678280)]
uint ConnectTimeout
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetConnectTimeout();
[DispId(1610678282)]
uint DataTimeout
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetDataTimeout();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
int NumberOfItems();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void NumberOfItemsToIndex(
out int plIncrementalCount,
out int plNotificationQueue,
out int plHighPriorityQueue);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
string URLBeingIndexed();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
uint GetURLIndexingState([MarshalAs(UnmanagedType.LPWStr), In] string psz);
uint GetURLIndexingState([MarshalAs(UnmanagedType.LPWStr)] string psz);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
object GetPersistentItemsChangedSink();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void RegisterViewForNotification(
[MarshalAs(UnmanagedType.LPWStr), In] string pszView,
[MarshalAs(UnmanagedType.Interface), In] object pViewChangedSink,
[MarshalAs(UnmanagedType.LPWStr)] string pszView,
[MarshalAs(UnmanagedType.Interface)] object pViewChangedSink,
out uint pdwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetItemsChangedSink(
[MarshalAs(UnmanagedType.Interface), In] object pISearchNotifyInlineSite,
[In] ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] object pISearchNotifyInlineSite,
ref Guid riid,
out IntPtr ppv,
out Guid pGUIDCatalogResetSignature,
out Guid pGUIDCheckPointSignature,
out uint pdwLastCheckPointNumber);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void UnregisterViewForNotification([In] uint dwCookie);
void UnregisterViewForNotification(uint dwCookie);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetExtensionClusion([MarshalAs(UnmanagedType.LPWStr), In] string pszExtension, [In] int fExclude);
void SetExtensionClusion([MarshalAs(UnmanagedType.LPWStr)] string pszExtension, int fExclude);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
object EnumerateExcludedExtensions();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
CSearchQueryHelper GetQueryHelper();
ISearchQueryHelper GetQueryHelper();
[DispId(1610678295)]
int DiacriticSensitivity
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
int GetDiacriticSensitivity();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
object GetCrawlScopeManager();
}

View File

@@ -5,85 +5,45 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[ComConversionLoss]
[Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF69")]
[InterfaceType(1)]
[ComImport]
public interface ISearchManager
[GeneratedComInterface]
public partial interface ISearchManager
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetIndexerVersionStr([MarshalAs(UnmanagedType.LPWStr)] out string ppszVersionString);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetIndexerVersion(out uint pdwMajor, out uint pdwMinor);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
IntPtr GetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName);
IntPtr GetParameter([MarshalAs(UnmanagedType.LPWStr)] string pszName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetParameter([MarshalAs(UnmanagedType.LPWStr), In] string pszName, [In] ref object pValue);
void SetParameter([MarshalAs(UnmanagedType.LPWStr)] string pszName, [MarshalAs(UnmanagedType.Interface)] ref object pValue);
[DispId(1610678276)]
string ProxyName
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetProxyName();
[DispId(1610678277)]
string BypassList
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetBypassList();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetProxy(
[In] object sUseProxy,
[In] int fLocalByPassProxy,
[In] uint dwPortNumber,
[MarshalAs(UnmanagedType.LPWStr), In] string pszProxyName,
[MarshalAs(UnmanagedType.LPWStr), In] string pszByPassList);
[MarshalAs(UnmanagedType.Interface)] object sUseProxy,
int fLocalByPassProxy,
uint dwPortNumber,
[MarshalAs(UnmanagedType.LPWStr)] string pszProxyName,
[MarshalAs(UnmanagedType.LPWStr)] string pszByPassList);
ISearchCatalogManager GetCatalog([MarshalAs(UnmanagedType.LPWStr)] string pszCatalog);
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetUserAgent();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
CSearchCatalogManager GetCatalog([MarshalAs(UnmanagedType.LPWStr), In] string pszCatalog);
object GetUseProxy();
[DispId(1610678280)]
string UserAgent
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
}
int GetLocalBypass();
[DispId(1610678282)]
object UseProxy
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678283)]
int LocalBypass
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678284)]
uint PortNumber
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
uint GetPortNumber();
}

View File

@@ -5,130 +5,60 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
[Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF63")]
[InterfaceType(1)]
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[GeneratedComInterface]
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1212:Property accessors should follow order", Justification = "The order of the property accessors must match the order in which the methods were defined in the vtable")]
public interface ISearchQueryHelper
public partial interface ISearchQueryHelper
{
[DispId(1610678272)]
string ConnectionString
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678273)]
uint QueryContentLocale
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678275)]
uint QueryKeywordLocale
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678277)]
object QueryTermExpansion
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678279)]
object QuerySyntax
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
[DispId(1610678281)]
string QueryContentProperties
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678283)]
string QuerySelectColumns
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678285)]
string QueryWhereRestrictions
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[DispId(1610678287)]
string QuerySorting
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: MarshalAs(UnmanagedType.LPWStr)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
get;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.LPWStr)]
string GenerateSQLFromUserQuery([MarshalAs(UnmanagedType.LPWStr), In] string pszQuery);
string GetConnectionString();
uint GetQueryContentLocale();
uint GetQueryKeywordLocale();
[return: MarshalAs(UnmanagedType.Interface)]
object GetQueryTermExpansion();
[return: MarshalAs(UnmanagedType.Interface)]
object GetQuerySyntax();
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetQueryContentProperties();
void SetQueryContentProperties([MarshalAs(UnmanagedType.LPWStr)] string pszProperties);
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetQuerySelectColumns();
void SetQuerySelectColumns([MarshalAs(UnmanagedType.LPWStr)] string pszColumns);
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetQueryWhereRestrictions();
void SetQueryWhereRestrictions([MarshalAs(UnmanagedType.LPWStr)] string pszRestrictions);
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetQuerySorting();
void SetQuerySorting([MarshalAs(UnmanagedType.LPWStr)] string pszSorting);
[return: MarshalAs(UnmanagedType.LPWStr)]
string GenerateSQLFromUserQuery([MarshalAs(UnmanagedType.LPWStr)] string pszQuery);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void WriteProperties(
[In] int itemID,
[In] uint dwNumberOfColumns,
[In] ref object pColumns,
[In] ref object pValues,
[In] ref object pftGatherModifiedTime);
int itemID,
uint dwNumberOfColumns,
[MarshalAs(UnmanagedType.Interface)] ref object pColumns,
[MarshalAs(UnmanagedType.Interface)] ref object pValues,
[MarshalAs(UnmanagedType.Interface)] ref object pftGatherModifiedTime);
[DispId(1610678291)]
int QueryMaxResults
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
[param: In]
set;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
get;
}
int GetQueryMaxResults();
void SetQueryMaxResults(int lMaxResults);
}

View File

@@ -2,12 +2,16 @@
// 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.Globalization;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
using Microsoft.CmdPal.Ext.Indexer.Indexer.SystemSearch;
using Microsoft.CmdPal.Ext.Indexer.Native;
namespace Microsoft.CmdPal.Ext.Indexer.Indexer.Utils;
internal sealed class QueryStringBuilder
internal sealed partial class QueryStringBuilder
{
private const string Properties = "System.ItemUrl, System.ItemNameDisplay, path, System.Search.EntryID, System.Kind, System.KindText";
private const string SystemIndex = "SystemIndex";
@@ -20,20 +24,36 @@ internal sealed class QueryStringBuilder
public static string GeneratePrimingQuery() => SelectQueryWithScopeAndOrderConditions;
private static readonly Guid CLSIDSearchManager = new Guid("7D096C5F-AC08-4F1F-BEB7-5C22C517CE39");
private static readonly Guid IIDISearchManager = new Guid("AB310581-AC80-11D1-8DF3-00C04FB6EF69");
private const uint CLSCTXINPROCSERVER = 1;
public static string GenerateQuery(string searchText, uint whereId)
{
if (queryHelper == null)
{
var searchManager = new CSearchManager();
ComWrappers cw = new StrategyBasedComWrappers();
Guid clsidSearchManager = CLSIDSearchManager;
Guid iidSearchManager = IIDISearchManager;
var hr = NativeMethods.CoCreateInstance(CLSIDSearchManager, IntPtr.Zero, CLSCTXINPROCSERVER, IIDISearchManager, out var searchManagerPtr);
if (hr != 0)
{
throw new ArgumentException("Failed to create SearchManager instance.");
}
var searchManager = (CSearchManager)cw.GetOrCreateObjectForComInstance(
searchManagerPtr, CreateObjectFlags.None);
ISearchCatalogManager catalogManager = searchManager.GetCatalog(SystemIndex);
queryHelper = catalogManager.GetQueryHelper();
queryHelper.QuerySelectColumns = Properties;
queryHelper.QueryContentProperties = "System.FileName";
queryHelper.QuerySorting = OrderConditions;
queryHelper.SetQuerySelectColumns(Properties);
queryHelper.SetQueryContentProperties("System.FileName");
queryHelper.SetQuerySorting(OrderConditions);
}
queryHelper.QueryWhereRestrictions = "AND " + ScopeFileConditions + "AND ReuseWhere(" + whereId.ToString(CultureInfo.InvariantCulture) + ")";
queryHelper.SetQueryWhereRestrictions(SelectQueryWithScope + " AND ReuseWhere(" + whereId.ToString(CultureInfo.InvariantCulture) + ")");
return queryHelper.GenerateSQLFromUserQuery(searchText);
}
}

View File

@@ -1,13 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\Common.Dotnet.CsWinRT.props" />
<PropertyGroup>
<Import Project="..\..\..\..\Common.Dotnet.AotCompatibility.props" />
<PropertyGroup>
<RootNamespace>Microsoft.CmdPal.Ext.Indexer</RootNamespace>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\WinUI3Apps\CmdPal</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWin32">
@@ -46,4 +50,8 @@
</EmbeddedResource>
</ItemGroup>
<PropertyGroup>
<DisableRuntimeMarshalling>true</DisableRuntimeMarshalling>
</PropertyGroup>
</Project>

View File

@@ -1,24 +1,139 @@
// 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 Windows.Win32.UI.Shell.PropertiesSystem;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
using VARTYPE = System.Runtime.InteropServices.VarEnum;
namespace Microsoft.CmdPal.Ext.Indexer.Native;
internal sealed class NativeHelpers
public sealed partial class NativeHelpers
{
public const uint SEEMASKINVOKEIDLIST = 12;
internal static class PropertyKeys
public struct PropertyKeys
{
public static readonly PROPERTYKEY PKEYItemNameDisplay = new() { fmtid = new System.Guid("B725F130-47EF-101A-A5F1-02608C9EEBAC"), pid = 10 };
public static readonly PROPERTYKEY PKEYItemUrl = new() { fmtid = new System.Guid("49691C90-7E17-101A-A91C-08002B2ECDA9"), pid = 9 };
public static readonly PROPERTYKEY PKEYKindText = new() { fmtid = new System.Guid("F04BEF95-C585-4197-A2B7-DF46FDC9EE6D"), pid = 100 };
public static readonly PropertyKey PKEYItemNameDisplay = new() { fmtid = new System.Guid("B725F130-47EF-101A-A5F1-02608C9EEBAC"), pid = 10 };
public static readonly PropertyKey PKEYItemUrl = new() { fmtid = new System.Guid("49691C90-7E17-101A-A91C-08002B2ECDA9"), pid = 9 };
public static readonly PropertyKey PKEYKindText = new() { fmtid = new System.Guid("F04BEF95-C585-4197-A2B7-DF46FDC9EE6D"), pid = 100 };
}
internal static class OleDb
[StructLayout(LayoutKind.Sequential)]
public struct PropertyKey
{
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "No, please do not change the name")]
public Guid fmtid;
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "No, please do not change the name")]
public int pid;
public PropertyKey(Guid fmtid, int pid)
{
this.fmtid = fmtid;
this.pid = pid;
}
}
[StructLayout(LayoutKind.Explicit, Pack = 8, CharSet = CharSet.Unicode)]
public struct PROPVARIANT
{
/// <summary>Value type tag.</summary>
[FieldOffset(0)]
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "No, please do not change the name")]
public ushort vt;
[FieldOffset(2)]
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "No, please do not change the name")]
public ushort wReserved1;
/// <summary>Reserved for future use.</summary>
[FieldOffset(4)]
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "No, please do not change the name")]
public ushort wReserved2;
/// <summary>Reserved for future use.</summary>
[FieldOffset(6)]
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "No, please do not change the name")]
public ushort wReserved3;
/// <summary>The decimal value when VT_DECIMAL.</summary>
[FieldOffset(0)]
internal decimal _decimal;
/// <summary>The raw data pointer.</summary>
[FieldOffset(8)]
internal IntPtr _ptr;
/// <summary>The FILETIME when VT_FILETIME.</summary>
[FieldOffset(8)]
internal System.Runtime.InteropServices.ComTypes.FILETIME _ft;
/// <summary>The value when a numeric value less than 8 bytes.</summary>
[FieldOffset(8)]
internal ulong _ulong;
public PROPVARIANT()
{
}
public PROPVARIANT(string value)
{
ArgumentNullException.ThrowIfNull(value);
vt = (ushort)VarEnum.VT_LPWSTR;
_ptr = Marshal.StringToCoTaskMemUni(value);
}
public VarEnum VarType { get => (VarEnum)vt; set => vt = (ushort)(VARTYPE)value; }
}
[CustomMarshaller(typeof(PROPVARIANT), MarshalMode.UnmanagedToManagedOut, typeof(PROPVARIANTOutMarshaller))]
[CustomMarshaller(typeof(PROPVARIANT), MarshalMode.ManagedToUnmanagedOut, typeof(PROPVARIANTOutMarshaller))]
public static partial class PROPVARIANTOutMarshaller
{
public static void Free(IntPtr managed)
{
Marshal.FreeCoTaskMem(managed);
}
public static PROPVARIANT ConvertToManaged(IntPtr unmanaged)
{
var obj = Marshal.GetObjectForIUnknown(unmanaged);
return (PROPVARIANT)obj;
}
public static nint ConvertToUnmanaged(PROPVARIANT managed)
{
var obj = Marshal.GetIUnknownForObject(managed);
return obj;
}
}
[CustomMarshaller(typeof(PROPVARIANT), MarshalMode.ManagedToUnmanagedRef, typeof(PROPVARIANTRefMarshaller))]
[CustomMarshaller(typeof(PROPVARIANT), MarshalMode.UnmanagedToManagedRef, typeof(PROPVARIANTRefMarshaller))]
public static partial class PROPVARIANTRefMarshaller
{
public static void Free(IntPtr managed)
{
Marshal.FreeCoTaskMem(managed);
}
public static PROPVARIANT ConvertToManaged(IntPtr unmanaged)
{
var obj = Marshal.GetObjectForIUnknown(unmanaged);
return (PROPVARIANT)obj;
}
public static nint ConvertToUnmanaged(PROPVARIANT managed)
{
var obj = Marshal.GetIUnknownForObject(managed);
return obj;
}
}
public static class OleDb
{
public static readonly Guid DbGuidDefault = new("C8B521FB-5CF3-11CE-ADE5-00AA0044773D");
}

View File

@@ -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;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
using static Microsoft.CmdPal.Ext.Indexer.Native.NativeHelpers;
namespace Microsoft.CmdPal.Ext.Indexer.Native;
public sealed partial class NativeMethods
{
public static readonly Guid PropertyStoreGUID = new Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99");
[LibraryImport("ole32.dll")]
[return: MarshalAs(UnmanagedType.U4)]
public static partial uint CoCreateInstance(
Guid rclsid,
IntPtr pUnkOuter,
uint dwClsContext,
Guid riid,
out IntPtr rReturnedComObject);
[LibraryImport("shell32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool ShellExecuteEx([MarshalUsing(typeof(SHELLEXECUTEINFOWMarshaller))]ref SHELLEXECUTEINFOW lpExecInfo);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHELLEXECUTEINFOW
{
public int cbSize;
public uint fMask;
public IntPtr hwnd;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpVerb;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpFile;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpParameters;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpDirectory;
public int nShow;
public IntPtr hInstApp;
public IntPtr lpIDList;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpClass;
public IntPtr hkeyClass;
public uint dwHotKey;
public IntPtr hIcon;
public IntPtr hProcess;
}
[CustomMarshaller(typeof(SHELLEXECUTEINFOW), MarshalMode.ManagedToUnmanagedRef, typeof(SHELLEXECUTEINFOWMarshaller))]
[CustomMarshaller(typeof(SHELLEXECUTEINFOW), MarshalMode.UnmanagedToManagedRef, typeof(SHELLEXECUTEINFOWMarshaller))]
public static partial class SHELLEXECUTEINFOWMarshaller
{
public static SHELLEXECUTEINFOW ConvertToManaged(IntPtr unmanaged)
{
var obj = Marshal.GetObjectForIUnknown(unmanaged);
return (SHELLEXECUTEINFOW)obj;
}
public static void Free(IntPtr? managed)
{
if (managed != null)
{
Marshal.ReleaseComObject(managed);
}
}
public static nint ConvertToUnmanaged(SHELLEXECUTEINFOW managed)
{
var obj = Marshal.GetIUnknownForObject(managed);
return obj;
}
}
[GeneratedComInterface]
[Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")]
public partial interface IPropertyStore
{
int GetCount(out uint cProps);
int GetAt(uint iProp, out NativeHelpers.PropertyKey pkey);
int GetValue(ref NativeHelpers.PropertyKey key, [MarshalUsing(typeof(PROPVARIANTOutMarshaller))] out NativeHelpers.PROPVARIANT gpv);
int SetValue(ref NativeHelpers.PropertyKey key, [MarshalUsing(typeof(PROPVARIANTRefMarshaller))] ref NativeHelpers.PROPVARIANT spv);
int Commit();
}
}

View File

@@ -1,11 +1,7 @@
DBID
SHOW_WINDOW_CMD
CoCreateInstance
GetErrorInfo
ICommandText
IDBCreateCommand
IDBCreateSession
IDBInitialize
IGetRow
IPropertyStore
ShellExecuteEx
IGetRow

View File

@@ -4,25 +4,22 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Indexer;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Storage.Streams;
namespace Microsoft.CmdPal.Ext.Indexer;
internal sealed partial class IndexerPage : DynamicListPage, IDisposable
{
private readonly List<IListItem> _indexerListItems = [];
private readonly SearchEngine _searchEngine;
private readonly bool disposeSearchEngine = true;
private SearchQuery _searchQuery = new();
private uint _queryCookie;
private uint _queryCookie = 10;
private string initialQuery = string.Empty;
public IndexerPage()
{
@@ -30,16 +27,31 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable
Icon = Icons.FileExplorer;
Name = Resources.Indexer_Title;
PlaceholderText = Resources.Indexer_PlaceholderText;
_searchEngine = new();
_queryCookie = 10;
}
public IndexerPage(string query, SearchEngine searchEngine, uint queryCookie, IList<IListItem> firstPageData)
{
Icon = Icons.FileExplorer;
Name = Resources.Indexer_Title;
_searchEngine = searchEngine;
_queryCookie = queryCookie;
_indexerListItems.AddRange(firstPageData);
initialQuery = query;
SearchText = query;
disposeSearchEngine = false;
}
public override void UpdateSearchText(string oldSearch, string newSearch)
{
if (oldSearch != newSearch)
if (oldSearch != newSearch && newSearch != initialQuery)
{
_ = Task.Run(() =>
{
Query(newSearch);
LoadMore();
initialQuery = string.Empty;
});
}
}
@@ -49,7 +61,9 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable
public override void LoadMore()
{
IsLoading = true;
FetchItems(20);
var results = _searchEngine.FetchItems(_indexerListItems.Count, 20, _queryCookie, out var hasMore);
_indexerListItems.AddRange(results);
HasMoreItems = hasMore;
IsLoading = false;
RaiseItemsChanged(_indexerListItems.Count);
}
@@ -58,70 +72,16 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable
{
++_queryCookie;
_indexerListItems.Clear();
_searchQuery.SearchResults.Clear();
_searchQuery.CancelOutstandingQueries();
if (query == string.Empty)
{
return;
}
Stopwatch stopwatch = new();
stopwatch.Start();
_searchQuery.Execute(query, _queryCookie);
stopwatch.Stop();
Logger.LogDebug($"Query time: {stopwatch.ElapsedMilliseconds} ms, query: \"{query}\"");
}
private void FetchItems(int limit)
{
if (_searchQuery != null)
{
var cookie = _searchQuery.Cookie;
if (cookie == _queryCookie)
{
var index = 0;
SearchResult result;
var hasMoreItems = _searchQuery.FetchRows(_indexerListItems.Count, limit);
while (!_searchQuery.SearchResults.IsEmpty && _searchQuery.SearchResults.TryDequeue(out result) && ++index <= limit)
{
IconInfo icon = null;
try
{
var stream = ThumbnailHelper.GetThumbnail(result.LaunchUri).Result;
if (stream != null)
{
var data = new IconData(RandomAccessStreamReference.CreateFromStream(stream));
icon = new IconInfo(data, data);
}
}
catch (Exception ex)
{
Logger.LogError("Failed to get the icon.", ex);
}
_indexerListItems.Add(new IndexerListItem(new IndexerItem
{
FileName = result.ItemDisplayName,
FullPath = result.LaunchUri,
})
{
Icon = icon,
});
}
HasMoreItems = hasMoreItems;
}
}
_searchEngine.Query(query, _queryCookie);
}
public void Dispose()
{
_searchQuery = null;
GC.SuppressFinalize(this);
if (disposeSearchEngine)
{
_searchEngine.Dispose();
GC.SuppressFinalize(this);
}
}
}

View File

@@ -123,6 +123,15 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Search for &quot;{0}&quot; in files.
/// </summary>
internal static string Indexer_fallback_searchPage_title {
get {
return ResourceManager.GetString("Indexer_fallback_searchPage_title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This file doesn&apos;t exist.
/// </summary>
@@ -168,6 +177,42 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Always on.
/// </summary>
internal static string Indexer_Settings_FallbackCommand_AlwaysOn {
get {
return ResourceManager.GetString("Indexer_Settings_FallbackCommand_AlwaysOn", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Only when file path exist.
/// </summary>
internal static string Indexer_Settings_FallbackCommand_FilePathExist {
get {
return ResourceManager.GetString("Indexer_Settings_FallbackCommand_FilePathExist", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Shows file search results on the top-level search results.
/// </summary>
internal static string Indexer_Settings_FallbackCommand_Mode {
get {
return ResourceManager.GetString("Indexer_Settings_FallbackCommand_Mode", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Always off.
/// </summary>
internal static string Indexer_Settings_FallbackCommand_Off {
get {
return ResourceManager.GetString("Indexer_Settings_FallbackCommand_Off", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Search files on this device.
/// </summary>

View File

@@ -156,10 +156,25 @@
<data name="Indexer_PlaceholderText" xml:space="preserve">
<value>Search for files and folders...</value>
</data>
<data name="Indexer_Settings_FallbackCommand_AlwaysOn" xml:space="preserve">
<value>Always on</value>
</data>
<data name="Indexer_Settings_FallbackCommand_Mode" xml:space="preserve">
<value>Shows file search results on the top-level search results</value>
</data>
<data name="Indexer_Settings_FallbackCommand_Off" xml:space="preserve">
<value>Always off</value>
</data>
<data name="Indexer_Settings_FallbackCommand_FilePathExist" xml:space="preserve">
<value>Only when file path exist</value>
</data>
<data name="Indexer_Subtitle" xml:space="preserve">
<value>Search files on this device</value>
</data>
<data name="Indexer_Title" xml:space="preserve">
<value>Search files</value>
</data>
<data name="Indexer_fallback_searchPage_title" xml:space="preserve">
<value>Search for "{0}" in files</value>
</data>
</root>

View File

@@ -0,0 +1,95 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Indexer;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Storage.Streams;
namespace Microsoft.CmdPal.Ext.Indexer;
public sealed partial class SearchEngine : IDisposable
{
private SearchQuery _searchQuery = new();
public void Query(string query, uint queryCookie)
{
// _indexerListItems.Clear();
_searchQuery.SearchResults.Clear();
_searchQuery.CancelOutstandingQueries();
if (query == string.Empty)
{
return;
}
Stopwatch stopwatch = new();
stopwatch.Start();
_searchQuery.Execute(query, queryCookie);
stopwatch.Stop();
Logger.LogDebug($"Query time: {stopwatch.ElapsedMilliseconds} ms, query: \"{query}\"");
}
public IList<IListItem> FetchItems(int offset, int limit, uint queryCookie, out bool hasMore)
{
hasMore = false;
var results = new List<IListItem>();
if (_searchQuery != null)
{
var cookie = _searchQuery.Cookie;
if (cookie == queryCookie)
{
var index = 0;
SearchResult result;
// var hasMoreItems = _searchQuery.FetchRows(_indexerListItems.Count, limit);
var hasMoreItems = _searchQuery.FetchRows(offset, limit);
while (!_searchQuery.SearchResults.IsEmpty && _searchQuery.SearchResults.TryDequeue(out result) && ++index <= limit)
{
IconInfo icon = null;
try
{
var stream = ThumbnailHelper.GetThumbnail(result.LaunchUri).Result;
if (stream != null)
{
var data = new IconData(RandomAccessStreamReference.CreateFromStream(stream));
icon = new IconInfo(data, data);
}
}
catch (Exception ex)
{
Logger.LogError("Failed to get the icon.", ex);
}
results.Add(new IndexerListItem(new IndexerItem
{
FileName = result.ItemDisplayName,
FullPath = result.LaunchUri,
})
{
Icon = icon,
});
}
hasMore = hasMoreItems;
}
}
return results;
}
public void Dispose()
{
_searchQuery = null;
GC.SuppressFinalize(this);
}
}

View File

@@ -9,6 +9,4 @@ namespace Microsoft.CmdPal.Ext.Shell;
internal sealed class Icons
{
internal static IconInfo RunV2 { get; } = IconHelpers.FromRelativePath("Assets\\Run.svg");
internal static IconInfo Folder { get; } = new("📁");
}

View File

@@ -15,10 +15,6 @@
<ItemGroup>
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.CommandLine" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DependentUpon>Resources.resx</DependentUpon>

View File

@@ -1,45 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Shell;
internal sealed partial class PathListItem : ListItem
{
private readonly Lazy<IconInfo> _icon;
private readonly bool _isDirectory;
public override IIconInfo? Icon { get => _icon.Value; set => base.Icon = value; }
public PathListItem(string path)
: base(new OpenUrlCommand(path))
{
var fileName = Path.GetFileName(path);
_isDirectory = Directory.Exists(path);
if (_isDirectory)
{
path = path + "\\";
fileName = fileName + "\\";
}
Title = fileName;
Subtitle = path;
TextToSuggest = path;
MoreCommands = [
new CommandContextItem(new CopyTextCommand(path))
];
_icon = new Lazy<IconInfo>(() =>
{
var iconStream = ThumbnailHelper.GetThumbnail(path).Result;
var icon = iconStream != null ? IconInfo.FromStream(iconStream) :
_isDirectory ? Icons.Folder : Icons.RunV2;
return icon;
});
}
}

View File

@@ -1,150 +0,0 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.CmdPal.Ext.Shell.Helpers;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Shell;
internal sealed partial class RunMainPage : DynamicListPage
{
private readonly ShellListPageHelpers _helper;
private readonly List<ListItem> _topLevelItems = new();
private List<ListItem> _historyItems = new();
private List<ListItem> _pathItems = new();
public RunMainPage(SettingsManager settingsManager)
{
Name = "Open"; // LOC!
Title = "Run commands"; // LOC!
Icon = Icons.RunV2;
PlaceholderText = "Type the name of a command to run"; // LOC!
_helper = new(settingsManager);
EmptyContent = new CommandItem()
{
Title = "Run commands",
Icon = Icons.RunV2,
};
var allAppsCommandItem = new ListItem(new NoOpCommand()
{
Name = "Open",
Icon = IconHelpers.FromRelativePath("Assets\\AllApps.svg"),
})
{
Title = "All apps",
Subtitle = "Search installed apps",
};
var calculatorCommandItem = new ListItem(new NoOpCommand()
{
Name = "Open",
Icon = IconHelpers.FromRelativePath("Assets\\Calculator.png"),
})
{
Title = "Calculator",
Subtitle = "Press = to type an equation",
};
// var fileSearchCommandItem = new ListItem(new NoOpCommand()
// {
// Name = "Open",
// Icon = IconHelpers.FromRelativePath("Assets\\FileExplorer.png"),
// })
// {
// Title = "Search files",
// Subtitle = "Search files on this device",
// };
_topLevelItems.Add(allAppsCommandItem);
_topLevelItems.Add(calculatorCommandItem);
// _topLevelItems.Add(fileSearchCommandItem);
}
public override void UpdateSearchText(string oldSearch, string newSearch)
{
// If the search text is the start of a path to a file (it might be a
// UNC path), then we want to list all the files that start with that text:
// 1. Check if the search text is a valid path
// 2. If it is, then list all the files that start with that text
var searchText = newSearch.Trim();
_historyItems = _helper.Query(searchText);
_historyItems.ForEach(i =>
{
i.Icon = Icons.RunV2;
i.Subtitle = string.Empty;
});
// TODO we can be smarter about only re-reading the filesystem if the
// new search is just the oldSearch+some chars
if (string.IsNullOrEmpty(searchText) || string.IsNullOrWhiteSpace(searchText))
{
_pathItems.Clear();
RaiseItemsChanged();
return;
}
var directoryPath = string.Empty;
var searchPattern = string.Empty;
// Check if the search text is a valid path
if (Path.IsPathRooted(searchText) && Path.GetDirectoryName(searchText) is string directoryName)
{
directoryPath = directoryName;
searchPattern = $"{Path.GetFileName(searchText)}*";
}
// we should also handle just drive roots, ala c:\ or d:\
else if (searchText.Length == 2 && searchText[1] == ':')
{
directoryPath = searchText + "\\";
searchPattern = $"*";
}
// Check if the search text is a valid UNC path
else if (searchText.StartsWith(@"\\", System.StringComparison.CurrentCultureIgnoreCase) && searchText.Contains(@"\\"))
{
directoryPath = searchText;
searchPattern = $"*";
}
// Check if the directory exists
if (Directory.Exists(directoryPath))
{
// Get all the files in the directory that start with the search text
var files = Directory.GetFileSystemEntries(directoryPath, searchPattern);
// Create a list of commands for each file
var commands = files.Select(PathToListItem).ToList();
// Add the commands to the list
_pathItems = commands;
}
else
{
_pathItems.Clear();
}
RaiseItemsChanged();
}
private ListItem PathToListItem(string path)
{
return new PathListItem(path);
}
public override IListItem[] GetItems()
{
return ListHelpers.FilterList(_topLevelItems, SearchText)
.Concat(_historyItems)
.Concat(_pathItems)
.ToArray();
}
}

View File

@@ -13,7 +13,6 @@ namespace Microsoft.CmdPal.Ext.Shell;
public partial class ShellCommandsProvider : CommandProvider
{
private readonly CommandItem _shellPageItem;
private readonly CommandItem _runMainPageItem;
private readonly SettingsManager _settingsManager = new();
private readonly FallbackCommandItem _fallbackItem;
@@ -35,18 +34,9 @@ public partial class ShellCommandsProvider : CommandProvider
new CommandContextItem(Settings.SettingsPage),
],
};
_runMainPageItem = new CommandItem(new RunMainPage(_settingsManager))
{
Icon = Icons.RunV2,
Title = "Run 2 electric boogaloo", // LOC!
Subtitle = Resources.cmd_plugin_description,
MoreCommands = [
new CommandContextItem(Settings.SettingsPage),
],
};
}
public override ICommandItem[] TopLevelCommands() => [_shellPageItem, _runMainPageItem];
public override ICommandItem[] TopLevelCommands() => [_shellPageItem];
public override IFallbackCommandItem[]? FallbackCommands() => [_fallbackItem];
}

View File

@@ -32,6 +32,7 @@ internal sealed partial class FallbackSystemCommandItem : FallbackCommandItem
{
if (string.IsNullOrWhiteSpace(query))
{
Command = null;
Title = string.Empty;
Subtitle = string.Empty;
return;
@@ -58,6 +59,7 @@ internal sealed partial class FallbackSystemCommandItem : FallbackCommandItem
if (result == null)
{
Command = null;
Title = string.Empty;
Subtitle = string.Empty;

View File

@@ -10,12 +10,12 @@ namespace Microsoft.CmdPal.Ext.System.Pages;
public sealed partial class SystemCommandPage : ListPage
{
private SettingsManager _settingsManager;
private readonly SettingsManager _settingsManager;
public SystemCommandPage(SettingsManager settingsManager)
{
Title = Resources.Microsoft_plugin_ext_system_page_name;
Name = Resources.Microsoft_plugin_ext_system_page_name;
Title = Resources.Microsoft_plugin_ext_system_page_title;
Name = Resources.Microsoft_plugin_command_name_open;
Icon = IconHelpers.FromRelativePath("Assets\\SystemCommand.svg");
_settingsManager = settingsManager;
ShowDetails = true;

View File

@@ -205,7 +205,7 @@ namespace Microsoft.CmdPal.Ext.System {
}
/// <summary>
/// Looks up a localized string similar to Windows System Command.
/// Looks up a localized string similar to System Commands.
/// </summary>
public static string Microsoft_plugin_ext_system_page_name {
get {
@@ -213,6 +213,15 @@ namespace Microsoft.CmdPal.Ext.System {
}
}
/// <summary>
/// Looks up a localized string similar to Windows System Commands.
/// </summary>
public static string Microsoft_plugin_ext_system_page_title {
get {
return ResourceManager.GetString("Microsoft_plugin_ext_system_page_title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Adapter name.
/// </summary>

View File

@@ -160,8 +160,11 @@
<data name="Microsoft_plugin_ext_settings_hideDisconnectedNetworkInfo" xml:space="preserve">
<value>Hide disconnected network info</value>
</data>
<data name="Microsoft_plugin_ext_system_page_title" xml:space="preserve">
<value>Windows System Commands</value>
</data>
<data name="Microsoft_plugin_ext_system_page_name" xml:space="preserve">
<value>Windows System Command</value>
<value>System Commands</value>
</data>
<data name="Microsoft_plugin_sys_AdapterName" xml:space="preserve">
<value>Adapter name</value>

View File

@@ -14,7 +14,7 @@ public partial class SystemCommandExtensionProvider : CommandProvider
private readonly ICommandItem[] _commands;
private static readonly SettingsManager _settingsManager = new();
public static readonly SystemCommandPage Page = new(_settingsManager);
private readonly FallbackSystemCommandItem _fallbackFileItem = new(_settingsManager);
private readonly FallbackSystemCommandItem _fallbackSystemItem = new(_settingsManager);
public SystemCommandExtensionProvider()
{
@@ -23,7 +23,7 @@ public partial class SystemCommandExtensionProvider : CommandProvider
_commands = [
new CommandItem(Page)
{
Title = Resources.Microsoft_plugin_ext_system_page_name,
Title = Resources.Microsoft_plugin_ext_system_page_title,
Icon = Page.Icon,
MoreCommands = [new CommandContextItem(_settingsManager.Settings.SettingsPage)],
},
@@ -38,5 +38,5 @@ public partial class SystemCommandExtensionProvider : CommandProvider
return _commands;
}
public override IFallbackCommandItem[] FallbackCommands() => [_fallbackFileItem];
public override IFallbackCommandItem[] FallbackCommands() => [_fallbackSystemItem];
}

View File

@@ -1,9 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<!-- Look at Directory.Build.props in root for common stuff as well -->
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
<Import Project="..\..\..\Common.Dotnet.FuzzTest.props" />
<PropertyGroup>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<Platforms>x64;ARM64</Platforms>
<LangVersion>latest</LangVersion>
<Platforms>x64;ARM64</Platforms>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>