Почему функция RemoveDirectory не удаляет самую верхнюю папку?
См. codeguru.com/forum/showthread.php?t=239271
При использовании функции ниже для удаления папок удаляются все папки, подпапки и файлы, кроме самой верхней папки. Скажи за путь 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 ("процесс не может получить доступ к файлу, потому что он используется другим процессом"), однако я не имею ни малейшего понятия после попытки с помощью проводника процесса.
3 ответа
В то время как вы можете удалить каталог таким способом, проще позволить системе сделать это за вас, позвонив SHFileOperation
прохождение FO_DELETE
, Помните, что вы должны дважды завершить нулем строку, которую вы передаете этому API.
Я считаю, что вы должны закрыть дескриптор файла перед рекурсивным вызовом. Что означает, что после выхода из рекурсивного вызова вы должны снова установить свой дескриптор файла на что-то подходящее.
SHFileOperation может быть лучшим решением; Я просто отвечаю на вопрос ОП, почему их код не работал так, как задумывалось.
См: 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);
}