From 3f87a0c4086e2502c324a0355eef6845e56434e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Pol=C3=A1=C5=A1ek?= Date: Wed, 24 Sep 2025 20:01:03 +0200 Subject: [PATCH] CmdPal: Add actionable hint to empty results in File Search extension (#41982) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary of the Pull Request This PR improves the user experience when no indexed files match the query in the File Search extension. - Show a hint on the empty results page when no indexed files are found. - Provide fallback actions: - Search entire PC – opens new File Explorer window with the query searched in This PC. - Open Windows Search settings – navigates to Windows Search settings to review indexed locations. image ## PR Checklist - [x] Related to: #38509 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- .../Pages/IndexerPage.cs | 51 +++++++++++++++---- .../Properties/Resources.Designer.cs | 30 ++++++++++- .../Properties/Resources.resx | 10 ++++ 3 files changed, 79 insertions(+), 12 deletions(-) diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Pages/IndexerPage.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Pages/IndexerPage.cs index f03452effb..3b09fcf149 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Pages/IndexerPage.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Pages/IndexerPage.cs @@ -4,6 +4,8 @@ using System; using System.Collections.Generic; +using System.Globalization; +using System.Text.Encodings.Web; using System.Threading.Tasks; using Microsoft.CmdPal.Ext.Indexer.Properties; using Microsoft.CommandPalette.Extensions; @@ -23,6 +25,9 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable private bool _isEmptyQuery = true; + private CommandItem _noSearchEmptyContent; + private CommandItem _nothingFoundEmptyContent; + public IndexerPage() { Id = "com.microsoft.indexer.fileSearch"; @@ -31,6 +36,7 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable PlaceholderText = Resources.Indexer_PlaceholderText; _searchEngine = new(); _queryCookie = 10; + CreateEmptyContent(); } public IndexerPage(string query, SearchEngine searchEngine, uint queryCookie, IList firstPageData) @@ -43,9 +49,42 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable initialQuery = query; SearchText = query; disposeSearchEngine = false; + CreateEmptyContent(); } - public override ICommandItem EmptyContent => GetEmptyContent(); + private void CreateEmptyContent() + { + _noSearchEmptyContent = new CommandItem(new NoOpCommand()) + { + Icon = Icon, + Title = Resources.Indexer_Subtitle, + Subtitle = Resources.Indexer_NoSearchQueryMessageTip, + }; + + _nothingFoundEmptyContent = new CommandItem(new AnonymousCommand(StartManualSearch) { Name = Resources.Indexer_Command_SearchAllFiles! }) + { + Icon = Icon, + Title = Resources.Indexer_NoResultsMessage, + Subtitle = Resources.Indexer_NoResultsMessageTip, + MoreCommands = [ + new CommandContextItem(new OpenUrlCommand("ms-settings:search") { Name = Resources.Indexer_Command_OpenIndexerSettings! }) + { + Title = Resources.Indexer_Command_SearchAllFiles!, + }, + ], + }; + } + + private void StartManualSearch() + { + // {20D04FE0-3AEA-1069-A2D8-08002B30309D} is CLSID for "This PC" + const string template = "search-ms:query={0}&crumb=location:::{{20D04FE0-3AEA-1069-A2D8-08002B30309D}}"; + var encodedSearchText = UrlEncoder.Default.Encode(SearchText); + var command = string.Format(CultureInfo.CurrentCulture, template, encodedSearchText); + ShellHelpers.OpenInShell(command); + } + + public override ICommandItem EmptyContent => _isEmptyQuery ? _noSearchEmptyContent : _nothingFoundEmptyContent; public override void UpdateSearchText(string oldSearch, string newSearch) { @@ -74,16 +113,6 @@ internal sealed partial class IndexerPage : DynamicListPage, IDisposable RaiseItemsChanged(_indexerListItems.Count); } - private CommandItem GetEmptyContent() - { - return new CommandItem(new NoOpCommand()) - { - Icon = Icon, - Title = _isEmptyQuery ? Resources.Indexer_Subtitle : Resources.Indexer_NoResultsMessage, - Subtitle = Resources.Indexer_NoResultsMessageTip, - }; - } - private void Query(string query) { ++_queryCookie; diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.Designer.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.Designer.cs index a78488a7f1..44b87b05e2 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.Designer.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.Designer.cs @@ -96,6 +96,15 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties { } } + /// + /// Looks up a localized string similar to Open Windows Search settings. + /// + internal static string Indexer_Command_OpenIndexerSettings { + get { + return ResourceManager.GetString("Indexer_Command_OpenIndexerSettings", resourceCulture); + } + } + /// /// Looks up a localized string similar to Open path in console. /// @@ -123,6 +132,15 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties { } } + /// + /// Looks up a localized string similar to Search all files. + /// + internal static string Indexer_Command_SearchAllFiles { + get { + return ResourceManager.GetString("Indexer_Command_SearchAllFiles", resourceCulture); + } + } + /// /// Looks up a localized string similar to Show in folder. /// @@ -187,7 +205,8 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties { } /// - /// Looks up a localized string similar to Tip: Improve your search result using filters like in Windows Explorer. (For example: type:directory). + /// Looks up a localized string similar to Nothing was found in the indexed locations. + ///You can try searching all files on this PC or adjust your indexing settings.. /// internal static string Indexer_NoResultsMessageTip { get { @@ -195,6 +214,15 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties { } } + /// + /// Looks up a localized string similar to Tip: Refine your search using filters, just like in File Explorer (e.g., type:directory).. + /// + internal static string Indexer_NoSearchQueryMessageTip { + get { + return ResourceManager.GetString("Indexer_NoSearchQueryMessageTip", resourceCulture); + } + } + /// /// Looks up a localized string similar to Search for files and folders.... /// diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.resx b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.resx index bbe8f0bd31..66504abed1 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.resx +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.resx @@ -184,6 +184,16 @@ No items found + Nothing was found in the indexed locations. +You can try searching all files on this PC or adjust your indexing settings. + + Tip: Refine your search using filters, just like in File Explorer (e.g., type:directory). + + Open Windows Search settings + + + Search all files + \ No newline at end of file