Почему функция RemoveDirectory не удаляет самую верхнюю папку? - PullRequest
3 голосов
/ 13 марта 2012

см. 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 ]

5 голосов
/ 13 марта 2012

Хотя вы можете удалить каталог таким способом, проще позволить системе сделать это за вас, позвонив по номеру SHFileOperation, передав FO_DELETE.Помните, что вы должны дважды завершить нулем строку, которую вы передаете этому API.

2 голосов
/ 28 августа 2012

Полагаю, вам нужно закрыть дескриптор файла перед рекурсивным вызовом.Это означает, что после выхода из рекурсивного вызова вы должны снова установить свой дескриптор файла на что-то более подходящее.

SHFileOperation может быть лучшим решением;Я просто отвечаю на вопрос ОП, почему их код не работал должным образом.

1 голос
/ 13 марта 2012

См: 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);
}
...