SHFileOperation(): возвращает ошибку в Release-версии
void CSysbackupDlg::DeleteFolder(CString & sName) // удаление указанной папки
{
CFileFind file;
CString str = "";
CString sMaskName = "";
BOOL bSuccess; // флаг: успешно ли удаление
int iError; // код ошибки для SHFileOperation() (0 => операция успешна)
sMaskName = sName + "\\*";
BOOL bfile = file.FindFile(sMaskName);
if ( bfile )
{
while ( bfile )
{
bfile = file.FindNextFile(); // индикатор: последний ли это файл в данной папке?
if ( file.IsDots() ) // если получаем точки ("." и "..")
continue;
if ( file.IsDirectory() ) // если найдена папка
{
str = file.GetFilePath(); // имя папки
DeleteFolder(str); // удаляем вложенные в найденную папку файлы (рекурсия)
bSuccess = RemoveDirectory(str); // удаляем саму папку
continue;
}
else // если найден файл
{
str = file.GetFilePath(); // имя файла
LPCTSTR lpStr = str.GetBuffer(str.GetLength() + 1);
SHFILEOPSTRUCT lpShfos;
lpShfos.hwnd = NULL;
lpShfos.wFunc = FO_DELETE;
lpShfos.pFrom = lpStr;
lpShfos.pTo = NULL;
lpShfos.fFlags = FOF_SILENT | FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI;
iError = SHFileOperation(&lpShfos);
// Обработка ошибок
........................
}
}
bSuccess = RemoveDirectory(sName); // удаляем уже пустую главную папку
}
}
В функцию DeleteFolder() передается имя папки, которую надо удалить. Перед удалением папки она чистится от вложенных в нее папок и файлов.
В Debug-версии все OK. А вот в Release - SHFileOperation() указанный файл не удаляется, и функция возвращает значение 1026 - файл не найден. Ошибка возникает при попытке удаления любого файла.
Почему?
Спасибо всем, кто ответит!
void CSysbackupDlg::DeleteFolder(CString & sName) // удаление указанной папки
{
CFileFind file;
CString str = "";
CString sMaskName = "";
BOOL bSuccess; // флаг: успешно ли удаление
int iError; // код ошибки для SHFileOperation() (0 => операция успешна)
sMaskName = sName + "\\*";
BOOL bfile = file.FindFile(sMaskName);
if ( bfile )
{
while ( bfile )
{
bfile = file.FindNextFile(); // индикатор: последний ли это файл в данной папке?
if ( file.IsDots() ) // если получаем точки ("." и "..")
continue;
if ( file.IsDirectory() ) // если найдена папка
{
str = file.GetFilePath(); // имя папки
DeleteFolder(str); // удаляем вложенные в найденную папку файлы (рекурсия)
bSuccess = RemoveDirectory(str); // удаляем саму папку
continue;
}
else // если найден файл
{
iError = DeleteFile(file.GetFilePath());
// Обработка ошибок
........................
}
}
bSuccess = RemoveDirectory(sName); // удаляем уже пустую главную папку
}
}
вот так не проще? а если охота использовать SHFileOperation то тогда лучше так:
void CSysbackupDlg::DeleteFolder(CString & sName) // удаление указанной папки
{
CFileFind file;
CString str = "";
CString sMaskName = "";
BOOL bSuccess; // флаг: успешно ли удаление
int iError,nLength; // код ошибки для SHFileOperation() (0 => операция успешна)
sMaskName = sName + "\\*";
BOOL bfile = file.FindFile(sMaskName);
if ( bfile )
{
while ( bfile )
{
bfile = file.FindNextFile(); // индикатор: последний ли это файл в данной папке?
if ( file.IsDots() ) // если получаем точки ("." и "..")
continue;
if ( file.IsDirectory() ) // если найдена папка
{
str = file.GetFilePath(); // имя папки
DeleteFolder(str); // удаляем вложенные в найденную папку файлы (рекурсия)
// этой папки уже нет её удалили в DeleteFolder()
// bSuccess = RemoveDirectory(str); // удаляем саму папку
continue;
}
else // если найден файл
{
str = str + (file.GetFilePath() + "*"); // имя файла + *
}
}
// это строка содержит имена файлов через звездочку и в конце еще * (потому что прибавляли "имя" + "*")
nLength = str.GetLength() + 1;
LPCTSTR lpStr = str.GetBuffer(nLength);
// заменяем все * на NULL (включая последнюю)
while (nLength)
{
nLength--;
if (lpStr[nLength]=='*') lpStr[nLength] = 0;
}
// строка lpStr: "имя1\0имя2\0....имяN\0\0"
SHFILEOPSTRUCT lpShfos;
lpShfos.hwnd = NULL;
lpShfos.wFunc = FO_DELETE;
lpShfos.pFrom = lpStr;
lpShfos.pTo = NULL;
lpShfos.fFlags = FOF_SILENT | FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI;
iError = SHFileOperation(&lpShfos);
// Обработка ошибок
........................
str.ReleaseBuffer();
}
bSuccess = RemoveDirectory(sName); // удаляем уже пустую главную папку
}
P.S. Забыл сказать, что твой error видима ф том, что строка передаваемая в структуре SHFILEOPSTRUCT далжна заканчиваца, на ДВА NULL
Попробовал также добавть '\0' в конец своей строки:
LPTSTR lpStr = str.GetBuffer(str.GetLength() + 1);
lpStr += '\0';
Не работает. Почему? И почему вообще в данном случае должно быть два нуля?
С уважением, Дмитрий
Цитата:
Originally posted by Doomych
Большое спасибо, помогло! Использовал второй вариант, с SHFileOperation().
Попробовал также добавть '\0' в конец своей строки:
LPTSTR lpStr = str.GetBuffer(str.GetLength() + 1);
lpStr += '\0';
Не работает. Почему? И почему вообще в данном случае должно быть два нуля?
С уважением, Дмитрий
Большое спасибо, помогло! Использовал второй вариант, с SHFileOperation().
Попробовал также добавть '\0' в конец своей строки:
LPTSTR lpStr = str.GetBuffer(str.GetLength() + 1);
lpStr += '\0';
Не работает. Почему? И почему вообще в данном случае должно быть два нуля?
С уважением, Дмитрий
видима ты имел в виду так:
int nLength = str.GetLength();
LPTSTR lpStr = str.GetBuffer(nLength + 2);
lpStr[nLength] = 0;
lpStr[nLength+1] = 0; // или что-то типа: *(short*)(lpStr+nLength) = 0;
Два NULL идентифицируют конец строки т.к. SHFileOperation принимает несколько имён файлов в строке, а разделитель между именами NULL.