2012-03-13 36 views
2

參考:codeguru.com/forum/showthread.php?t=239271爲什麼RemoveDirectory函數不會刪除最頂層的文件夾?

當使用下面的功能刪除文件夾時,除最上面的文件夾外,所有文件夾,子文件夾和文件都將被刪除。對於路徑c:\folder1\folder2說,除folder2之外,folder2之下的所有東西都被刪除。

BOOL DeleteDirectory(const TCHAR* sPath) 
{ 
    HANDLE hFind; // file handle 
    WIN32_FIND_DATA FindFileData; 

    TCHAR DirPath[MAX_PATH]; 
    TCHAR FileName[MAX_PATH]; 

    _tcscpy(DirPath,sPath); 
    _tcscat(DirPath,_T("\\")); 
    _tcscpy(FileName,sPath); 
    _tcscat(FileName,_T("\\*")); // searching all files 
    int nRet = 0; 
    hFind = FindFirstFile(FileName, &FindFileData); // find the first file 
    if(hFind != INVALID_HANDLE_VALUE) 
    { 
     do 
     { 
      if(IsDots(FindFileData.cFileName)) 
       continue; //if not directory continue 

      _tcscpy(FileName + _tcslen(DirPath), FindFileData.cFileName); 
      if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 
      { 
       // we have found a directory, recurse 
       if(!DeleteDirectory(FileName)) 
        break; // directory couldn't be deleted 
      } 
      else 
      { 
       if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) 
        _wchmod(FileName, _S_IWRITE); // change read-only file mode 

       if(!DeleteFile(FileName)) 
        break; // file couldn't be deleted 
      } 
     }while(FindNextFile(hFind, &FindFileData)); 

     nRet = FindClose(hFind); // closing file handle 
    } 

    return RemoveDirectory(sPath); // remove the empty (maybe not) directory and returns zero when RemoveDirectory function fails 
} 

任何幫助找到問題的讚賞。 在調試過程中,我注意到,FindClose功能被成功關閉文件句柄,但GetLastError返航32(「因爲它正由另一個進程的進程無法訪問文件」),但我有一個過程的探索者試圖後沒有任何線索。

+0

在DeleteFile失敗後立即調用GetLastError並找出它給出的錯誤。這應該可以幫助你解決這個問題。 – Jay 2012-03-13 12:15:36

回答

5

雖然你可以用這種方式刪除一個目錄,但讓系統通過調用SHFileOperation通過FO_DELETE可以更簡單。請記住,您必須對您傳遞給此API的字符串進行雙重空置終止。

+0

此功能已由IFileOperation在Windows Vista中替換。我的應用程序需要支持上述所有Windows版本,包括Windows XP。 – Martin 2012-03-13 13:05:40

+3

該功能在Vista中尚未被替換。該文檔是完全錯誤的。 'SHFileOperation'可以在Win2k,XP,Vista,7上運行。它可以在Windows 8上運行.MS並不習慣於刪除函數。一旦他們留在他們身邊。 – 2012-03-13 13:07:12

+0

我盲目信任MSDN文檔。感謝大衛爲你的時間。 – Martin 2012-03-13 13:18:03

1

參考:HTTP://www.codeguru.com/forum/archive/index.php/t-337897.html
下面給出的是代碼刪除目錄使用SHFileOperation

bool DeleteDirectory(LPCTSTR lpszDir, bool noRecycleBin = true) 
{ 
    int len = _tcslen(lpszDir); 
    TCHAR* pszFrom = new TCHAR[len+4]; //4 to handle wide char 
    //_tcscpy(pszFrom, lpszDir); //todo:remove warning//;//convet wchar to char* 
    wcscpy_s (pszFrom, len+2, lpszDir); 
    pszFrom[len] = 0; 
    pszFrom[len+1] = 0; 

    SHFILEOPSTRUCT fileop; 
    fileop.hwnd = NULL; // no status display 
    fileop.wFunc = FO_DELETE; // delete operation 
    fileop.pFrom = pszFrom; // source file name as double null terminated string 
    fileop.pTo = NULL; // no destination needed 
    fileop.fFlags = FOF_NOCONFIRMATION|FOF_SILENT; // do not prompt the user 

    if(!noRecycleBin) 
     fileop.fFlags |= FOF_ALLOWUNDO; 

    fileop.fAnyOperationsAborted = FALSE; 
    fileop.lpszProgressTitle  = NULL; 
    fileop.hNameMappings   = NULL; 

    int ret = SHFileOperation(&fileop); //SHFileOperation returns zero if successful; otherwise nonzero 
    delete [] pszFrom; 
    return (0 == ret); 
} 
+1

這是來自http://www.codeguru.com/forum/showthread.php?t=239271的剪切和粘貼,我覺得你應該承認它是這樣的。 – 2012-03-13 13:41:13

+2

抱歉,我當時很匆忙,現在我已經添加了確認。 – Martin 2012-03-13 14:21:42

2

我相信您必須在遞歸調用之前關閉文件句柄。這意味着在退出遞歸調用之後,您必須再次將您的文件句柄設置爲適當的。

SHFileOperation可能是一個更好的解決方案;我只是回答了OP爲什麼他們的代碼不能按預期工作的問題。

相關問題