From 70fb48e09d9010149af7a856c1ace36b03242bd9 Mon Sep 17 00:00:00 2001 From: Marco Gavelli Date: Wed, 23 Dec 2020 18:04:51 +0100 Subject: [PATCH 1/4] Fix search inside hidden folders --- Files/Filesystem/Search/FolderSearch.cs | 162 ++++++++++++++---------- Files/Views/ModernShellPage.xaml.cs | 4 +- 2 files changed, 95 insertions(+), 71 deletions(-) diff --git a/Files/Filesystem/Search/FolderSearch.cs b/Files/Filesystem/Search/FolderSearch.cs index 3f4f749ac2b0..2566e7a45ce8 100644 --- a/Files/Filesystem/Search/FolderSearch.cs +++ b/Files/Filesystem/Search/FolderSearch.cs @@ -14,9 +14,99 @@ namespace Files.Filesystem.Search { internal class FolderSearch { - public static async Task> SearchForUserQueryTextAsync(string userText, string WorkingDirectory, int maxItemCount = 10) + public static async Task> SearchForUserQueryTextAsync(string userText, string WorkingDirectory, IShellPage associatedInstance, int maxItemCount = 10) + { + var returnedItems = new ObservableCollection(); + var hiddenOnlyFromWin32 = false; + var workingDir = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(WorkingDirectory); + if (workingDir) + { + foreach (var item in await SearchWithStorageFolder(userText, workingDir, maxItemCount)) + { + returnedItems.Add(item); + } + hiddenOnlyFromWin32 = true; + } + if (!hiddenOnlyFromWin32 || App.AppSettings.AreHiddenItemsVisible) + { + foreach (var item in await SearchWithWin32(userText, WorkingDirectory, hiddenOnlyFromWin32, maxItemCount)) + { + returnedItems.Add(item); + } + } + + return returnedItems; + } + + private static async Task> SearchWithWin32(string userText, string WorkingDirectory, bool hiddenOnly, int maxItemCount = 10) + { + var returnedItems = new List(); + (IntPtr hFile, WIN32_FIND_DATA findData) = await Task.Run(() => + { + FINDEX_INFO_LEVELS findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic; + int additionalFlags = FIND_FIRST_EX_LARGE_FETCH; + IntPtr hFileTsk = FindFirstFileExFromApp(WorkingDirectory + "\\*.*", findInfoLevel, out WIN32_FIND_DATA findDataTsk, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero, + additionalFlags); + return (hFileTsk, findDataTsk); + }).WithTimeoutAsync(TimeSpan.FromSeconds(5)); + + if (hFile != IntPtr.Zero) + { + await Task.Run(() => + { + var hasNextFile = false; + do + { + var itemPath = Path.Combine(WorkingDirectory, findData.cFileName); + if (((FileAttributes)findData.dwFileAttributes & FileAttributes.System) != FileAttributes.System || !App.AppSettings.AreSystemItemsHidden) + { + if ((((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) != FileAttributes.Hidden && !hiddenOnly) || App.AppSettings.AreHiddenItemsVisible) + { + if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) != FileAttributes.Directory) + { + returnedItems.Add(new ListedItem(null) + { + PrimaryItemAttribute = StorageItemTypes.File, + ItemName = findData.cFileName, + ItemPath = itemPath, + IsHiddenItem = true, + LoadFileIcon = false, + LoadUnknownTypeGlyph = true, + LoadFolderGlyph = false, + ItemPropertiesInitialized = true + }); + } + else if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory) + { + if (findData.cFileName != "." && findData.cFileName != "..") + { + returnedItems.Add(new ListedItem(null) + { + PrimaryItemAttribute = StorageItemTypes.Folder, + ItemName = findData.cFileName, + ItemPath = itemPath, + IsHiddenItem = true, + LoadFileIcon = false, + LoadUnknownTypeGlyph = false, + LoadFolderGlyph = true, + ItemPropertiesInitialized = true + }); + } + } + } + } + + hasNextFile = FindNextFile(hFile, out findData); + } while (hasNextFile); + + FindClose(hFile); + }); + } + return returnedItems; + } + + private static async Task> SearchWithStorageFolder(string userText, StorageFolder workingDir, int maxItemCount = 10) { - var workingDir = await StorageFolder.GetFolderFromPathAsync(WorkingDirectory); QueryOptions options = new QueryOptions() { FolderDepth = FolderDepth.Deep, @@ -33,7 +123,7 @@ public static async Task> SearchForUserQueryTex var itemQueryResult = workingDir.CreateItemQueryWithOptions(options); uint stepSize = maxItemCount == 10 ? (uint)maxItemCount : 500; IReadOnlyList items = await itemQueryResult.GetItemsAsync(0, stepSize); - var returnedItems = new ObservableCollection(); + var returnedItems = new List(); uint index = 0; while (items.Count > 0) { @@ -98,72 +188,6 @@ public static async Task> SearchForUserQueryTex break; } } - - if (App.AppSettings.AreHiddenItemsVisible) - { - (IntPtr hFile, WIN32_FIND_DATA findData) = await Task.Run(() => - { - FINDEX_INFO_LEVELS findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic; - int additionalFlags = FIND_FIRST_EX_LARGE_FETCH; - IntPtr hFileTsk = FindFirstFileExFromApp(WorkingDirectory + "\\*.*", findInfoLevel, out WIN32_FIND_DATA findDataTsk, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero, - additionalFlags); - return (hFileTsk, findDataTsk); - }).WithTimeoutAsync(TimeSpan.FromSeconds(5)); - - if (hFile != IntPtr.Zero) - { - await Task.Run(() => - { - var hasNextFile = false; - do - { - var itemPath = Path.Combine(WorkingDirectory, findData.cFileName); - if (((FileAttributes)findData.dwFileAttributes & FileAttributes.System) != FileAttributes.System || !App.AppSettings.AreSystemItemsHidden) - { - if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) == FileAttributes.Hidden) - { - if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) != FileAttributes.Directory) - { - returnedItems.Add(new ListedItem(null) - { - PrimaryItemAttribute = StorageItemTypes.File, - ItemName = findData.cFileName, - ItemPath = itemPath, - IsHiddenItem = true, - LoadFileIcon = false, - LoadUnknownTypeGlyph = true, - LoadFolderGlyph = false, - ItemPropertiesInitialized = true - }); - } - else if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory) - { - if (findData.cFileName != "." && findData.cFileName != "..") - { - returnedItems.Add(new ListedItem(null) - { - PrimaryItemAttribute = StorageItemTypes.Folder, - ItemName = findData.cFileName, - ItemPath = itemPath, - IsHiddenItem = true, - LoadFileIcon = false, - LoadUnknownTypeGlyph = false, - LoadFolderGlyph = true, - ItemPropertiesInitialized = true - }); - } - } - } - } - - hasNextFile = FindNextFile(hFile, out findData); - } while (hasNextFile); - - FindClose(hFile); - }); - } - } - return returnedItems; } } diff --git a/Files/Views/ModernShellPage.xaml.cs b/Files/Views/ModernShellPage.xaml.cs index f5145be0cd04..2ea626741e72 100644 --- a/Files/Views/ModernShellPage.xaml.cs +++ b/Files/Views/ModernShellPage.xaml.cs @@ -164,7 +164,7 @@ private async void ModernShellPage_SearchTextChanged(AutoSuggestBox sender, Auto { if (!string.IsNullOrWhiteSpace(sender.Text)) { - sender.ItemsSource = await FolderSearch.SearchForUserQueryTextAsync(sender.Text, FilesystemViewModel.WorkingDirectory); + sender.ItemsSource = await FolderSearch.SearchForUserQueryTextAsync(sender.Text, FilesystemViewModel.WorkingDirectory, this); } else { @@ -183,7 +183,7 @@ private async void ModernShellPage_SearchQuerySubmitted(AutoSuggestBox sender, A AssociatedTabInstance = this, IsSearchResultPage = true, SearchPathParam = FilesystemViewModel.WorkingDirectory, - SearchResults = await FolderSearch.SearchForUserQueryTextAsync(args.QueryText, FilesystemViewModel.WorkingDirectory, -1) + SearchResults = await FolderSearch.SearchForUserQueryTextAsync(args.QueryText, FilesystemViewModel.WorkingDirectory, this, -1) }); App.InteractionViewModel.IsContentLoadingIndicatorVisible = false; } From 451d830e781a599d0c515f1d5c2e1e765a286c22 Mon Sep 17 00:00:00 2001 From: Marco Gavelli Date: Wed, 23 Dec 2020 22:38:14 +0100 Subject: [PATCH 2/4] Oder search, fix search in hidden folders --- Files/Filesystem/Search/FolderSearch.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Files/Filesystem/Search/FolderSearch.cs b/Files/Filesystem/Search/FolderSearch.cs index 2566e7a45ce8..416265559f52 100644 --- a/Files/Filesystem/Search/FolderSearch.cs +++ b/Files/Filesystem/Search/FolderSearch.cs @@ -29,7 +29,8 @@ public static async Task> SearchForUserQueryTex } if (!hiddenOnlyFromWin32 || App.AppSettings.AreHiddenItemsVisible) { - foreach (var item in await SearchWithWin32(userText, WorkingDirectory, hiddenOnlyFromWin32, maxItemCount)) + foreach (var item in await SearchWithWin32(userText, WorkingDirectory, hiddenOnlyFromWin32, + maxItemCount - returnedItems.Count)) { returnedItems.Add(item); } @@ -45,7 +46,7 @@ private static async Task> SearchWithWin32(string userText, st { FINDEX_INFO_LEVELS findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic; int additionalFlags = FIND_FIRST_EX_LARGE_FETCH; - IntPtr hFileTsk = FindFirstFileExFromApp(WorkingDirectory + "\\*.*", findInfoLevel, out WIN32_FIND_DATA findDataTsk, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero, + IntPtr hFileTsk = FindFirstFileExFromApp(WorkingDirectory + $"\\*{userText}*.*", findInfoLevel, out WIN32_FIND_DATA findDataTsk, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero, additionalFlags); return (hFileTsk, findDataTsk); }).WithTimeoutAsync(TimeSpan.FromSeconds(5)); @@ -57,10 +58,15 @@ await Task.Run(() => var hasNextFile = false; do { + if (returnedItems.Count >= maxItemCount) + { + break; + } var itemPath = Path.Combine(WorkingDirectory, findData.cFileName); if (((FileAttributes)findData.dwFileAttributes & FileAttributes.System) != FileAttributes.System || !App.AppSettings.AreSystemItemsHidden) { - if ((((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) != FileAttributes.Hidden && !hiddenOnly) || App.AppSettings.AreHiddenItemsVisible) + var isHidden = ((FileAttributes)findData.dwFileAttributes & FileAttributes.Hidden) == FileAttributes.Hidden; + if ((!isHidden && !hiddenOnly) || (isHidden && App.AppSettings.AreHiddenItemsVisible)) { if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) != FileAttributes.Directory) { @@ -113,6 +119,7 @@ private static async Task> SearchWithStorageFolder(string user IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties, UserSearchFilter = string.IsNullOrWhiteSpace(userText) ? null : userText, }; + options.SortOrder.Clear(); options.SortOrder.Add(new SortEntry() { PropertyName = "System.Search.Rank", From 9dc4cc21a31772caf038979941bbeba41f18fbce Mon Sep 17 00:00:00 2001 From: Marco Gavelli Date: Wed, 23 Dec 2020 22:56:04 +0100 Subject: [PATCH 3/4] Fix search max count --- Files/Filesystem/Search/FolderSearch.cs | 16 ++++++---------- Files/MultilingualResources/Files.hu-HU.xlf | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Files/Filesystem/Search/FolderSearch.cs b/Files/Filesystem/Search/FolderSearch.cs index 416265559f52..fb0ec458d14d 100644 --- a/Files/Filesystem/Search/FolderSearch.cs +++ b/Files/Filesystem/Search/FolderSearch.cs @@ -17,6 +17,8 @@ internal class FolderSearch public static async Task> SearchForUserQueryTextAsync(string userText, string WorkingDirectory, IShellPage associatedInstance, int maxItemCount = 10) { var returnedItems = new ObservableCollection(); + maxItemCount = maxItemCount < 0 ? int.MaxValue : maxItemCount; + var hiddenOnlyFromWin32 = false; var workingDir = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(WorkingDirectory); if (workingDir) @@ -128,7 +130,7 @@ private static async Task> SearchWithStorageFolder(string user options.SetPropertyPrefetch(Windows.Storage.FileProperties.PropertyPrefetchOptions.None, null); options.SetThumbnailPrefetch(Windows.Storage.FileProperties.ThumbnailMode.ListView, 24, Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale); var itemQueryResult = workingDir.CreateItemQueryWithOptions(options); - uint stepSize = maxItemCount == 10 ? (uint)maxItemCount : 500; + uint stepSize = Math.Min(500, (uint)maxItemCount); IReadOnlyList items = await itemQueryResult.GetItemsAsync(0, stepSize); var returnedItems = new List(); uint index = 0; @@ -185,15 +187,9 @@ private static async Task> SearchWithStorageFolder(string user } } } - if (maxItemCount != 10) - { - index += stepSize; - items = await itemQueryResult.GetItemsAsync(index, stepSize); - } - else - { - break; - } + index += items.Count; + stepSize = Math.Min(500, (uint)(maxItemCount - returnedItems.Count)); + items = await itemQueryResult.GetItemsAsync(index, stepSize); } return returnedItems; } diff --git a/Files/MultilingualResources/Files.hu-HU.xlf b/Files/MultilingualResources/Files.hu-HU.xlf index 822dea96604c..6dd01725e9bc 100644 --- a/Files/MultilingualResources/Files.hu-HU.xlf +++ b/Files/MultilingualResources/Files.hu-HU.xlf @@ -1933,4 +1933,4 @@ - + \ No newline at end of file From c7f1b79470ae01441799a4c2569567104f1ead6c Mon Sep 17 00:00:00 2001 From: Marco Gavelli Date: Thu, 24 Dec 2020 00:04:54 +0100 Subject: [PATCH 4/4] Fix build --- Files/Filesystem/Search/FolderSearch.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Files/Filesystem/Search/FolderSearch.cs b/Files/Filesystem/Search/FolderSearch.cs index fb0ec458d14d..e72903323691 100644 --- a/Files/Filesystem/Search/FolderSearch.cs +++ b/Files/Filesystem/Search/FolderSearch.cs @@ -187,7 +187,7 @@ private static async Task> SearchWithStorageFolder(string user } } } - index += items.Count; + index += (uint)items.Count; stepSize = Math.Min(500, (uint)(maxItemCount - returnedItems.Count)); items = await itemQueryResult.GetItemsAsync(index, stepSize); }