mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-10 21:41:51 +02:00
EnumerateFileSystemInfos uses EnumerationOptions (#6933)
* Changed EnumerateFileSystemInfos to EnumerationOptions we don't have to catch the exceptions ourself. * Change Matchtype to mimic old search method. Co-authored-by: p-storm <paul.de.man@gmail.com>
This commit is contained in:
@@ -42,8 +42,8 @@ namespace Microsoft.Plugin.Folder.UnitTests
|
|||||||
queryFileSystemInfoMock.Setup(r => r.Exists(It.IsAny<string>()))
|
queryFileSystemInfoMock.Setup(r => r.Exists(It.IsAny<string>()))
|
||||||
.Returns<string>(path => ContainsDirectory(path));
|
.Returns<string>(path => ContainsDirectory(path));
|
||||||
|
|
||||||
queryFileSystemInfoMock.Setup(r => r.MatchFileSystemInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<SearchOption>()))
|
queryFileSystemInfoMock.Setup(r => r.MatchFileSystemInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
|
||||||
.Returns<string, string, SearchOption>(MatchFileSystemInfo);
|
.Returns<string, string, bool>(MatchFileSystemInfo);
|
||||||
|
|
||||||
_queryFileSystemInfoMock = queryFileSystemInfoMock;
|
_queryFileSystemInfoMock = queryFileSystemInfoMock;
|
||||||
}
|
}
|
||||||
@@ -66,25 +66,23 @@ namespace Microsoft.Plugin.Folder.UnitTests
|
|||||||
return trimEnd;
|
return trimEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, SearchOption searchOption)
|
private static IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, bool isRecursive)
|
||||||
{
|
{
|
||||||
Func<string, bool> folderSearchFunc;
|
Func<string, bool> folderSearchFunc;
|
||||||
Func<string, bool> fileSearchFunc;
|
Func<string, bool> fileSearchFunc;
|
||||||
switch (searchOption)
|
switch (isRecursive)
|
||||||
{
|
{
|
||||||
case SearchOption.TopDirectoryOnly:
|
case false:
|
||||||
folderSearchFunc = s => s.Equals(search, StringComparison.CurrentCultureIgnoreCase);
|
folderSearchFunc = s => s.Equals(search, StringComparison.CurrentCultureIgnoreCase);
|
||||||
|
|
||||||
var regexSearch = TrimDirectoryEnd(search);
|
var regexSearch = TrimDirectoryEnd(search);
|
||||||
|
|
||||||
fileSearchFunc = s => Regex.IsMatch(s, $"^{Regex.Escape(regexSearch)}[^\\\\]*$");
|
fileSearchFunc = s => Regex.IsMatch(s, $"^{Regex.Escape(regexSearch)}[^\\\\]*$");
|
||||||
break;
|
break;
|
||||||
case SearchOption.AllDirectories:
|
case true:
|
||||||
folderSearchFunc = s => s.StartsWith(search, StringComparison.CurrentCultureIgnoreCase);
|
folderSearchFunc = s => s.StartsWith(search, StringComparison.CurrentCultureIgnoreCase);
|
||||||
fileSearchFunc = s => s.StartsWith(search, StringComparison.CurrentCultureIgnoreCase);
|
fileSearchFunc = s => s.StartsWith(search, StringComparison.CurrentCultureIgnoreCase);
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(searchOption), searchOption, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var directories = DirectoryExist.Where(s => folderSearchFunc(s))
|
var directories = DirectoryExist.Where(s => folderSearchFunc(s))
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ namespace Microsoft.Plugin.Folder.Sources
|
|||||||
{
|
{
|
||||||
public interface IQueryFileSystemInfo : IDirectoryWrapper
|
public interface IQueryFileSystemInfo : IDirectoryWrapper
|
||||||
{
|
{
|
||||||
IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, SearchOption searchOption);
|
IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, bool isRecursive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,41 +12,22 @@ namespace Microsoft.Plugin.Folder.Sources
|
|||||||
{
|
{
|
||||||
public class QueryFileSystemInfo : DirectoryWrapper, IQueryFileSystemInfo
|
public class QueryFileSystemInfo : DirectoryWrapper, IQueryFileSystemInfo
|
||||||
{
|
{
|
||||||
public IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, SearchOption searchOption)
|
public IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, bool isRecursive)
|
||||||
{
|
{
|
||||||
// search folder and add results
|
// search folder and add results
|
||||||
var directoryInfo = new DirectoryInfo(search);
|
var directoryInfo = new DirectoryInfo(search);
|
||||||
var fileSystemInfos = directoryInfo.EnumerateFileSystemInfos(incompleteName, searchOption);
|
var fileSystemInfos = directoryInfo.EnumerateFileSystemInfos(incompleteName, new EnumerationOptions()
|
||||||
|
|
||||||
return SafeEnumerateFileSystemInfos(fileSystemInfos)
|
|
||||||
.Where(fileSystemInfo => (fileSystemInfo.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden)
|
|
||||||
.Select(CreateDisplayFileInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(IEnumerable<FileSystemInfo> fileSystemInfos)
|
|
||||||
{
|
|
||||||
using (var enumerator = fileSystemInfos.GetEnumerator())
|
|
||||||
{
|
{
|
||||||
while (true)
|
MatchType = MatchType.Win32,
|
||||||
{
|
RecurseSubdirectories = isRecursive,
|
||||||
FileSystemInfo currentFileSystemInfo;
|
IgnoreInaccessible = true,
|
||||||
try
|
ReturnSpecialDirectories = false,
|
||||||
{
|
AttributesToSkip = FileAttributes.Hidden,
|
||||||
if (!enumerator.MoveNext())
|
MatchCasing = MatchCasing.PlatformDefault,
|
||||||
{
|
});
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentFileSystemInfo = enumerator.Current;
|
return fileSystemInfos
|
||||||
}
|
.Select(CreateDisplayFileInfo);
|
||||||
catch (UnauthorizedAccessException)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return currentFileSystemInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DisplayFileInfo CreateDisplayFileInfo(FileSystemInfo fileSystemInfo)
|
private static DisplayFileInfo CreateDisplayFileInfo(FileSystemInfo fileSystemInfo)
|
||||||
|
|||||||
@@ -36,15 +36,10 @@ namespace Microsoft.Plugin.Folder.Sources
|
|||||||
return search.Any(c => SpecialSearchChars.Contains(c));
|
return search.Any(c => SpecialSearchChars.Contains(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SearchOption GetSearchOptions(string query)
|
public static bool RecursiveSearch(string query)
|
||||||
{
|
{
|
||||||
// give the ability to search all folder when it contains a >
|
// give the ability to search all folder when it contains a >
|
||||||
if (query.Any(c => c.Equals('>')))
|
return query.Any(c => c.Equals('>'));
|
||||||
{
|
|
||||||
return SearchOption.AllDirectories;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SearchOption.TopDirectoryOnly;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Do not want to change the behavior of the application, but want to enforce static analysis")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Do not want to change the behavior of the application, but want to enforce static analysis")]
|
||||||
@@ -99,9 +94,9 @@ namespace Microsoft.Plugin.Folder.Sources
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (search, incompleteName) = processed;
|
var (search, incompleteName) = processed;
|
||||||
var searchOption = GetSearchOptions(incompleteName);
|
var isRecursive = RecursiveSearch(incompleteName);
|
||||||
|
|
||||||
if (searchOption == SearchOption.AllDirectories)
|
if (isRecursive)
|
||||||
{
|
{
|
||||||
// match everything before and after search term using supported wildcard '*', ie. *searchterm*
|
// match everything before and after search term using supported wildcard '*', ie. *searchterm*
|
||||||
if (string.IsNullOrEmpty(incompleteName))
|
if (string.IsNullOrEmpty(incompleteName))
|
||||||
@@ -117,7 +112,7 @@ namespace Microsoft.Plugin.Folder.Sources
|
|||||||
yield return new CreateOpenCurrentFolderResult(search);
|
yield return new CreateOpenCurrentFolderResult(search);
|
||||||
|
|
||||||
// Note: Take 1000 is so that you don't search the whole system before you discard
|
// Note: Take 1000 is so that you don't search the whole system before you discard
|
||||||
var lookup = _queryFileSystemInfo.MatchFileSystemInfo(search, incompleteName, searchOption)
|
var lookup = _queryFileSystemInfo.MatchFileSystemInfo(search, incompleteName, isRecursive)
|
||||||
.Take(1000)
|
.Take(1000)
|
||||||
.ToLookup(r => r.Type);
|
.ToLookup(r => r.Type);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user