IEnumerable <TResult> EnumerateFiles <TResult>(string path, string pattern, bool recursive, IFindResultHandler <TResult> findResultHandler, bool caseSensitive) { string filename = Path.Combine(path, pattern); Win32FindData findData = new Win32FindData(); SearchAdditionalFlags flags = SearchAdditionalFlags.LargeFetch; if (caseSensitive) { flags |= SearchAdditionalFlags.CaseSensitive; } List <string> directories = null; if (recursive) { directories = new List <string>(); } using (SafeFindHandle findHandle = FindFirstFileEx(filename, FIndexInfoLevels.Basic, findData, FIndexSearchOps.NameMatch, IntPtr.Zero, flags)) { bool ok = !findHandle.IsInvalid; while (ok) { if (findResultHandler.IsResultOK(path, findData)) { yield return(findResultHandler.GetResult(path, findData)); } if (recursive && (findData.FileAttributes & FileAttributes.Directory) != 0) { directories.Add(findData.FileName); } ok = FindNextFile(findHandle, findData); } int errorCode = Marshal.GetLastWin32Error(); if (!(errorCode == ERROR_FILE_NOT_FOUND || errorCode == ERROR_NO_MORE_FILES || errorCode == ERROR_PATH_NOT_FOUND)) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } if (recursive) { foreach (string directory in directories) { foreach (TResult innerFile in EnumerateFiles <TResult>(Path.Combine(path, directory), pattern, true, findResultHandler, caseSensitive)) { yield return(innerFile); } } } }
static extern SafeFindHandle FindFirstFileEx(string fileName, FIndexInfoLevels infoLevel, [In, Out] Win32FindData fineFileData, FIndexSearchOps searchOp, IntPtr searchFilter, SearchAdditionalFlags flags);