private async static Task <IReadOnlyList <IStorageItem> > EnumerateFileQuery(string path, string searchPattern, SearchOption searchOption, SearchTarget searchTarget) { // Get a StorageFolder for "path" string fullPath = Path.GetFullPath(path); StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(fullPath).TranslateWinRTTask(fullPath, isDirectory: true); // Construct a query for the search. QueryOptions query = new QueryOptions(); // Translate SearchOption into FolderDepth query.FolderDepth = searchOption == SearchOption.AllDirectories ? FolderDepth.Deep : FolderDepth.Shallow; // Construct an AQS filter string normalizedSearchPattern = PathHelpers.NormalizeSearchPattern(searchPattern); if (normalizedSearchPattern.Length == 0) { // An empty searchPattern will return no results and requires no AQS parsing. return(new IStorageItem[0]); } else { // Parse the query as an ItemPathDisplay filter. string searchPath = PathHelpers.GetFullSearchString(fullPath, normalizedSearchPattern); string aqs = "System.ItemPathDisplay:~\"" + searchPath + "\""; query.ApplicationSearchFilter = aqs; // If the filtered path is deeper than the given user path, we need to get a new folder for it. // This occurs when someone does something like Enumerate("C:\first\second\", "C:\first\second\third\*"). // When AllDirectories is set this isn't an issue, but for TopDirectoryOnly we have to do some special work // to make sure something is actually returned when the searchPattern is a subdirectory of the path. // To do this, we attempt to get a new StorageFolder for the subdirectory and return an empty enumerable // if we can't. string searchPatternDirName = Path.GetDirectoryName(normalizedSearchPattern); string userPath = string.IsNullOrEmpty(searchPatternDirName) ? fullPath : Path.Combine(fullPath, searchPatternDirName); if (userPath != folder.Path) { folder = await StorageFolder.GetFolderFromPathAsync(userPath).TranslateWinRTTask(userPath, isDirectory: true); } } // Execute our built query if (searchTarget == SearchTarget.Files) { StorageFileQueryResult queryResult = folder.CreateFileQueryWithOptions(query); return(await queryResult.GetFilesAsync().TranslateWinRTTask(folder.Path, isDirectory: true)); } else if (searchTarget == SearchTarget.Directories) { StorageFolderQueryResult queryResult = folder.CreateFolderQueryWithOptions(query); return(await queryResult.GetFoldersAsync().TranslateWinRTTask(folder.Path, isDirectory: true)); } else { StorageItemQueryResult queryResult = folder.CreateItemQueryWithOptions(query); return(await queryResult.GetItemsAsync().TranslateWinRTTask(folder.Path, isDirectory: true)); } }
internal Win32FileSystemEnumerableIterator(string path, string originalUserPath, string searchPattern, SearchOption searchOption, SearchResultHandler <TSource> resultHandler) { Contract.Requires(path != null); Contract.Requires(originalUserPath != null); Contract.Requires(searchPattern != null); Contract.Requires(searchOption == SearchOption.AllDirectories || searchOption == SearchOption.TopDirectoryOnly); Contract.Requires(resultHandler != null); _oldMode = Interop.mincore.SetErrorMode(Interop.mincore.SEM_FAILCRITICALERRORS); string normalizedSearchPattern = PathHelpers.NormalizeSearchPattern(searchPattern); if (normalizedSearchPattern.Length == 0) { _empty = true; } else { _resultHandler = resultHandler; _searchOption = searchOption; _fullPath = Path.GetFullPath(path); string fullSearchString = PathHelpers.GetFullSearchString(_fullPath, normalizedSearchPattern); _normalizedSearchPath = Path.GetDirectoryName(fullSearchString); // normalize search criteria _searchCriteria = GetNormalizedSearchCriteria(fullSearchString, _normalizedSearchPath); // fix up user path string searchPatternDirName = Path.GetDirectoryName(normalizedSearchPattern); _userPath = string.IsNullOrEmpty(searchPatternDirName) ? originalUserPath : Path.Combine(originalUserPath, searchPatternDirName); _searchData = new PathPair(_userPath, _normalizedSearchPath); CommonInit(); } }