Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

SHFileOperation(): возвращает ошибку в Release-версии

321
21 января 2003 года
Doomych
124 / / 20.01.2000
Вот код:

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 - файл не найден. Ошибка возникает при попытке удаления любого файла.
Почему?

Спасибо всем, кто ответит!
380
21 января 2003 года
Arestov
285 / / 20.09.2000

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
321
22 января 2003 года
Doomych
124 / / 20.01.2000
Большое спасибо, помогло! Использовал второй вариант, с SHFileOperation().

Попробовал также добавть '\0' в конец своей строки:
LPTSTR lpStr = str.GetBuffer(str.GetLength() + 1);
lpStr += '\0';
Не работает. Почему? И почему вообще в данном случае должно быть два нуля?

С уважением, Дмитрий
380
23 января 2003 года
Arestov
285 / / 20.09.2000
Цитата:
Originally posted by Doomych
Большое спасибо, помогло! Использовал второй вариант, с 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.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог