Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.224.59.231] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Очень часто в форуме возникают вопросы про удаление директорий.
Штука достаточно простая, большинство бы и так догадалось как делать, но иногда нужно просто держать сухим нужный кусок кода, вынуть его из заначки и применить. BOOL RemoveDir( IN LPCTSTR szDir) { BOOL fRet = FALSE; if( !szDir) return fRet; size_t tReplaceLen = 1; WIN32_FIND_DATA fd = {}; // Формируем строку пути для поиска файлов std::basic_string< TCHAR > stPath( szDir); stPath += _T( "\\*"); HANDLE hFind = FindFirstFile( stPath.c_str(), &fd); if( hFind != INVALID_HANDLE_VALUE) { fRet = TRUE; do { // Игнорируем вхождения в каталог if( !(_tcscmp( fd.cFileName, _T( ".")) && _tcscmp( fd.cFileName, _T( ".."))) ) continue; // Формруем полный путь к файлу/каталогу stPath.replace( stPath.end() - tReplaceLen, stPath.end(), fd.cFileName); tReplaceLen = _tcslen( fd.cFileName); // Прикапываем для следующего replace if( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) fRet = RemoveDir( stPath.c_str()); // Удаляем все потроха найденного каталога else { // Просто удаляем найденный файл if( fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) SetFileAttributes( stPath.c_str(), FILE_ATTRIBUTE_NORMAL); fRet = DeleteFile( stPath.c_str()); } } while( fRet && FindNextFile( hFind, &fd)); FindClose( hFind); // Заключительный момент - удалить пустой каталог... if( fRet) fRet = RemoveDirectory( szDir); } return fRet; } |
Сообщ.
#2
,
|
|
|
Че-то понамешано, STL, CRT, WinAPI...
|
Сообщ.
#3
,
|
|
|
Цитата Uncle_Bob @ Че-то понамешано, STL, CRT, WinAPI... stl - для того, чтоб не вляпатся в MAX_PATH. Попробуй создать в тотале путь более 260 символов и скопировать что-нить в эту диру... Можно канечна обойтись и без stl, но зачем мудрить? crt - ну, можно убрать сравнение строк и написать условие проверки на два символа. апи - ммм, предлагаешь на мфс заменить? |
Сообщ.
#4
,
|
|
|
ЗЫ. Кстати, эти пережитки с MAX_PATH могут к таким глюкам приводить. Я када писал свой плаг к тоталу, не раз попадал на это ограничение. Писал Гислеру, но он пока тока обещает увеличить свои буффера
|
Сообщ.
#5
,
|
|
|
Да я не против, просто лично по мне либо одно, либо другое, либо третье
STL+API, CRT+API, MFC-only, WinAPI-only что-нить в этом роде |
Сообщ.
#6
,
|
|
|
Да я понимаю что не против
Просто, стл базируется на црт, т.ч. связка STL+API-CRT не осуществима в принципе. Оставлять только апи - это значит ручками мараться со стековой/свободной памятью. Если используемые возможности облегчают написание кода и его понимание, то такое использование должно только приветствоваться. |
Сообщ.
#7
,
|
|
|
Удаление директории
#include "shellapi.h" #pragma comment( lib, "shell32.lib" ) // добавить shell32.lib // вариант для Unicode int Remove_dirW(LPCWSTR pPath) { SHFILEOPSTRUCTW sh; ZeroMemory(&sh,sizeof(SHFILEOPSTRUCTW)); sh.wFunc = FO_DELETE; sh.pFrom = pPath; //удаляемая директория //(путь в формате Unicode, завершающийся 2-мя NULL-терминаторами...) sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT; return SHFileOperationW(&sh); } // Для Ansi int Remove_dirA(LPCTSTR pPath) { SHFILEOPSTRUCTA sh; ZeroMemory(&sh,sizeof(SHFILEOPSTRUCTA)); sh.wFunc = FO_DELETE; sh.pFrom = pPath; //удаляемая директория //(путь в формате Ansi, завершающийся NULL-терминатором...) sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT; return SHFileOperationA(&sh); } //Пример: void primer() { Remove_dirW(L"WidePath\0"); // Unicode Remove_dirA("AnsiPath"); // Ansi } или Под VCL // полное удаление каталога при помощи рекурсивного обхода всех файлов и вложенных папок bool DeleteDir(AnsiString DirName) { TSearchRec sr; if (DirName.Length()) { if (!FindFirst(DirName+"\\*.*",faAnyFile,sr)) do { if (!(sr.Name=="." || sr.Name==".."))// это удалять не надо if (((sr.Attr & faDirectory) == faDirectory ) || (sr.Attr == faDirectory))// найдена папка { FileSetAttr(DirName+"\\"+sr.Name, faDirectory );// сброс всяких read-only DeleteDir(DirName+"\\"+sr.Name);//рекурсивно удаляем содержимое RemoveDir(DirName + "\\"+sr.Name);// удаляем теперь уже пустую папку } else// иначе найден файл { FileSetAttr(DirName+"\\"+sr.Name, 0);// сброс всяких read-only DeleteFile(DirName+"\\"+sr.Name);// удаляем файл } } while (!FindNext(sr));// ищем опять, пока не найдем все FindClose(sr); } RemoveDir(DirName); return true; } |
Сообщ.
#8
,
|
|
|
В первую функцию BOOL RemoveDir( IN LPCTSTR szDir) неплохо бы добавить некоторые параметры и возможности, типа BOOL bForceRemoveHiddenFiles, BOOL bForceRemoveSystemFiles, BOOL bForceRemoveReadOnlyFiles. Думаю, значение понятно
Универсальнее было бы 8) |
Сообщ.
#9
,
|
|
|
Цитата MinLexx @ Универсальнее было бы 8) Неа, не будет. Как ты себе это представляешь? Если встретятся удалять системные, а вот скрытые при этом не трогать? Тогда и дира не удалится, т.к. останется не пустой... |
Сообщ.
#10
,
|
|
|
mad_avenger, подправь свою Remove_dir. Укажи необходимые инклуды, убери билдеровский хэндл окна и подправь параметр Path, чтоб функция поддерживала уникод. Кроме этого, необходимо указать, что Path обязан завершатся двумя нуль-терминаторами. Иначе просто не будет работать...
По vcl-ской сказать ничего не могу, не помню я уже билдеровское |
Сообщ.
#11
,
|
|
|
Цитата Ace @ Цитата MinLexx @ Универсальнее было бы 8) Неа, не будет. Как ты себе это представляешь? Если встретятся удалять системные, а вот скрытые при этом не трогать? Тогда и дира не удалится, т.к. останется не пустой... Именно, если встретятся скрытые файлы при не установленном bForceRemoveHiddenFiles или если встретятся системные при не установленном bForceRemoveSystemFiles или если встретятся рид-онли при не установленном bForceRemoveReadOnlyFiles, то возвращать FALSE и прерывать удаление каталога. Или как вариант, предварительно проверять каталог на наличие возможных таких вот ошибочных ситуаций, ничего не удаляя, и если всё ОК, то удалять всё, иначе вернуть FALSE Первый вариант проще, удалять, пока удаляется 8) |
Сообщ.
#12
,
|
|
|
Неа. Данное творение (твои флаги) - частный случай использования. Думаю, что достаточно за базу взять исходник RemoveDir, и дописать необходимые "дополнительные" возможности...
|
Сообщ.
#13
,
|
|
|
Цитата Ace @ По vcl-ской сказать ничего не могу, не помню я уже билдеровское Спасибо за коммент! Сейчас сделаю. Так бы не заметил... |
Сообщ.
#14
,
|
|
|
А символические ссылки приведенные куски кода корректно обрабатывают?
|
Сообщ.
#15
,
|
|
|
Аффтора!
Я юзуюсь по ХР и MFC(где-то от 99 года) . Тут слыхом не слыхивали за TSearchRec и SHFILEOPSTRUCTW. Где их можна нарыть-то? |