/// <summary> /// /// </summary> /// <param name="targetDirectory">標的目錄</param> /// <param name="extensionFilters">副檔名過濾</param> /// <param name="realtimeActionWhenFind">發現檔案時, 即時執行項目 (避免掃描回傳時間過久, 可以在發現檔案的第一時間執行)</param> /// <returns></returns> private IList <string> RecursiveScan( string targetDirectory, string[] extensionFilters = null, Action <string> realtimeActionWhenFind = null, Action <string> whenEnterNewDir = null) { IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); WinApi.WIN32_FIND_DATAW findData; IntPtr findHandle = INVALID_HANDLE_VALUE; //檢查目錄前, 通常用於外部呼叫者定義顯示掃目錄 //於console 中顯示掃描目錄 if (whenEnterNewDir != null) { whenEnterNewDir(targetDirectory); } var info = new List <string>(); try { findHandle = WinApi.FindFirstFileW(targetDirectory + @"\*", out findData); if (findHandle != INVALID_HANDLE_VALUE) { do { if (findData.cFileName == "." || findData.cFileName == "..") { continue; } string fullpath = targetDirectory + (targetDirectory.EndsWith("\\") ? "" : "\\") + findData.cFileName; if ((findData.dwFileAttributes & System.IO.FileAttributes.Directory) != 0) { //為目錄時遞迴 info.AddRange(RecursiveScan(fullpath, extensionFilters, realtimeActionWhenFind, whenEnterNewDir)); } else { var extension = ZlpPathHelper.GetExtension(fullpath); //副檔名過濾 (前一個方法已全部轉小寫, 故此處以小寫比對) if (extensionFilters != null && ZlpPathHelper.GetExtension(fullpath).ToLower().NotIn(extensionFilters)) { continue; } //取得完整路徑 (使用 ZlpPathHelper 避免路徑過長) var fileFullPath = ZlpPathHelper.GetFullPath(fullpath); //執行即時Action (exception 外層自己控制) if (realtimeActionWhenFind != null) { realtimeActionWhenFind(fileFullPath); } info.Add(fileFullPath); } }while (WinApi.FindNextFile(findHandle, out findData)); } } finally { if (findHandle != INVALID_HANDLE_VALUE) { WinApi.FindClose(findHandle); } } return(info); }