MFC 無內建「刪除非空目錄」函式。本文提供 DeleteDirectory 遞迴函式,使用 CFileFind 列舉檔案與子目錄,逐一刪除檔案並遞迴處理子目錄,最後移除目錄本身。
bool DeleteDirectory(LPCTSTR dirPath)
{
CFileFind finder;
CString searchPath = dirPath;
searchPath.TrimRight(_T('\\'));
searchPath += _T("\\*.*");
BOOL bFound = finder.FindFile(searchPath);
while (bFound) {
bFound = finder.FindNextFile();
if (finder.IsDots()) continue; // 跳過 . 和 ..
CString fullPath = finder.GetFilePath();
if (finder.IsDirectory()) {
if (!DeleteDirectory(fullPath)) return false; // 遞迴
} else {
if (!DeleteFile(fullPath)) return false; // 刪除檔案
}
}
finder.Close();
// 移除空目錄
return RemoveDirectory(dirPath) != 0;
}
CString targetDir = _T("D:\\Temp\\MyFolder");
if (PathFileExists(targetDir)) {
if (DeleteDirectory(targetDir)) {
AfxMessageBox(_T("刪除成功"));
} else {
AfxMessageBox(_T("刪除失敗,請檢查權限或檔案是否被佔用"));
}
}
CFileFind::GetFilePath() 直接回傳完整路徑,避免手動拼接錯誤。IsDots() 必須檢查,否則會陷入無限遞迴。DeleteFile 失敗常見原因:檔案唯讀、被其他程序開啟、權限不足。可先 SetFileAttributes(..., FILE_ATTRIBUTE_NORMAL) 移除唯讀。RemoveDirectory 僅能刪除**空**目錄,確保遞迴已清空內容。\\\\?\\ 或使用 Unicode 版 API。
bool DeleteDirectoryEx(LPCTSTR dirPath, DWORD* pLastError = NULL)
{
CFileFind finder;
CString search = dirPath; search.TrimRight(_T('\\')); search += _T("\\*.*");
BOOL bFound = finder.FindFile(search);
while (bFound) {
bFound = finder.FindNextFile();
if (finder.IsDots()) continue;
CString path = finder.GetFilePath();
if (finder.IsDirectory()) {
if (!DeleteDirectoryEx(path, pLastError)) return false;
} else {
SetFileAttributes(path, FILE_ATTRIBUTE_NORMAL); // 移除唯讀
if (!DeleteFile(path)) {
if (pLastError) *pLastError = GetLastError();
return false;
}
}
}
finder.Close();
if (!RemoveDirectory(dirPath)) {
if (pLastError) *pLastError = GetLastError();
return false;
}
return true;
}