Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопрос по SHFileOperation и удаление 
:(
    Опции темы
den1977
  Дата 23.8.2010, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 23.8.2010

Репутация: нет
Всего: нет



Из папки 'C:\Test\' нужно удалить все файлы подкаталоги (оставив саму папку 'C:\Test\' )

Делаю так: 
Код

uses ShellApi

procedure TForm1.Button1Click(Sender: TObject);
var sh : SHFILEOPSTRUCT;
begin
sh.Wnd := Application.Handle;
sh.wFunc := FO_DELETE;
sh.pFrom := 'C:\Test\*.*';
sh.pTo := nil;
sh.fFlags := FOF_NOCONFIRMATION + FOF_SILENT;
sh.fAnyOperationsAborted := False;
sh.hNameMappings := nil;
sh.lpszProgressTitle := nil;
SHFileOperation(sh);
end;


В целом работает (удаляет из указанной папки все как надо), но если вдруг попадается занятый файл, то выдается сообщение и удаление прекращается.

user posted image

Как сделать чтобы вместо вывода сообщения - стало - пропустить занятые файлы и продолжить удаление остальных файлов и папок?? 

Если можно, то пожайлуста внесите нужные изменения в код или дайте примерчик как это сделать!

PM MAIL   Вверх
kami
Дата 23.8.2010, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 22
Всего: 72



Код

sh.fFlags := FOF_NOCONFIRMATION + FOF_SILENT+ FOF_NOERRORUI;


Это сообщение отредактировал(а) kami - 23.8.2010, 12:26
PM MAIL WWW   Вверх
Alexeis
Дата 23.8.2010, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(den1977 @  23.8.2010,  11:13 Найти цитируемый пост)
пропустить занятые файлы

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

Добавлено через 1 минуту и 13 секунд
kami, что-то мне подсказывает, что FOF_NOERRORUI просто не выкинет сообщение об ошибке, но реально произведет отмену всей операции.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
den1977
  Дата 23.8.2010, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 23.8.2010

Репутация: нет
Всего: нет



Да действительно если написать:

Код

sh.fFlags := FOF_NOCONFIRMATION + FOF_SILENT+ FOF_NOERRORUI;


Получается отключение показа сообщение об ошибке, но дальнейшее удаление все равно отменяется!!!  smile 

Но как пропустить занятые файлы (и/или папки)  smile  и продолжить удаление остальных файлов и папок??  smile 


PM MAIL   Вверх
Alexeis
Дата 23.8.2010, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(den1977 @  23.8.2010,  12:43 Найти цитируемый пост)
Но как пропустить занятые файлы (и/или папки) 


Я бы сделал используя код аналогичный этому http://forum.vingrad.ru/topic-82343.html


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
den1977
  Дата 23.8.2010, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 23.8.2010

Репутация: нет
Всего: нет



Цитата(Alexeis @  23.8.2010,  13:54 Найти цитируемый пост)
Я бы сделал используя код аналогичный этому http://forum.vingrad.ru/topic-82343.html


Я конечно извеняюсь, но чем мне поможет "рекурсивный обход дерева каталогов" в данной ситуации, ведь если начать удалять все согластно полученного списка, то все-равно когда SHFILEOPSTRUCT наткнется на занятый файл получится то-же самое  smile  , ведь и без списка когда нет занятых файлов SHFILEOPSTRUCT прекрастно все удаляет  smile  

Это сообщение отредактировал(а) den1977 - 23.8.2010, 14:13
PM MAIL   Вверх
Alexeis
Дата 23.8.2010, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(den1977 @  23.8.2010,  13:10 Найти цитируемый пост)
ведь если начать удалять все согластно полученного списка, то все-равно когда SHFILEOPSTRUCT наткнется на занятый файл получится то-же самое

  А зачем тут SHFILEOPSTRUCT ? Файл/пустую диреторию можно удалить при помощи DeleteFile() . Результат можно совсем не проверять, все что не сможет так и останется.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
den1977
  Дата 23.8.2010, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 23.8.2010

Репутация: нет
Всего: нет



Попробовал последовать совету Alexeis Вроде все работает как мне надо, но навсякий случай попробовал выводить перед удалением результаты поиска в memo1 и увидел что имена там отбражаются довольно странно  smile  (скорее всего я тут где-то, что-то напутал  smile )
Может кто проверит и исправит то, что не так smile  А то я чего-то запутался smile  Да и получить в дальнейшем глюки опасаюсь  
Код

procedure DelAllFind(path: string);
    var sr:Tsearchrec;// Описываем структуру, которую использует для поиска система
  found,i:integer; // найдено или нет
begin
  found:=FindFirst(path + '*.*', FaAnyfile, sr);
  while (found = 0) do // если хоть что-то найдено
   begin
    if (sr.name <> '.') and (sr.name <> '..') then
    begin // если это не указатели на корневые каталоги, то чтото нашли
        DelAllFind(path+sr.name);
        form1.memo1.lines.append(path+sr.name);
        DeleteFile(path+sr.name);
      if (sr.attr and FaDirectory) = FaDirectory then
// ага вот поддиректория - вызываем себя рекурсивно, но с поиском уже в этой директории
        begin
          DelAllFind(path+sr.name+'\');
          form1.memo1.lines.append(path+sr.name+'\');
          DeleteFile(path+sr.name);
          RemoveDir(path+sr.name+'\');
        end;
      end;
   found:=findnext(sr); // есть ли еще файлы или каталоги
   end;
   FindClose(sr); // поиск закончен - нужно освободить память
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
DelAllFind('c:\test\');
end;


И ксати может кто все-таки поможет с изначальным вопросм по SHFILEOPSTRUCT  smile 

Это сообщение отредактировал(а) den1977 - 23.8.2010, 15:51
PM MAIL   Вверх
Alexeis
Дата 23.8.2010, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



  А зачем делать DelAllFind(path+sr.name); для файлов? файл же не папка чтобы его перечислять.

Кроме того
DeleteFile(path+sr.name);
RemoveDir(path+sr.name+'\');

это что за "двойной удар"?


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
den1977
  Дата 23.8.2010, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 23.8.2010

Репутация: нет
Всего: нет



Учел замечания Alexeis - мда перестарался я чуток   smile 
Вроде так правильнее, пожалуйста проверьте и исправьте если, что не так  smile 

Подскажите пожалуйста - заметил, что если файл или папка имеют атрибут "только чтение", то они остаются, что и куда нужно добавить в этот код для удаления файлов или папок независимо от атрибутов?   smile 

Код

procedure DelAllFind(path: string);
    var sr:Tsearchrec;// Описываем структуру, которую использует для поиска система
  found,i:integer; // найдено или нет
begin
  found:=FindFirst(path + '*.*', FaAnyfile, sr);
  while (found = 0) do // если хоть что-то найдено
   begin
    if (sr.name <> '.') and (sr.name <> '..') then
    begin // если это не указатели на корневые каталоги, то чтото нашли
          Form1.Memo1.lines.append(path+sr.name);
          DeleteFile(path+sr.name);
      if (sr.attr and FaDirectory) = FaDirectory then
// ага вот поддиректория - вызываем себя рекурсивно, но с поиском уже в этой директории
        begin
          DelAllFind(path+sr.name+'\');
          Form1.memo1.lines.append(path+sr.name+'\');
          RemoveDir(path+sr.name+'\');
        end;
      end;
   found:=findnext(sr); // есть ли еще файлы или каталоги
   end;
   FindClose(sr); // поиск закончен - нужно освободить память
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
DelAllFind('c:\test\');
end;


PS.:
Может кто все-таки поможет с изначальным вопросм по SHFILEOPSTRUCT  smile 

Это сообщение отредактировал(а) den1977 - 23.8.2010, 21:43
PM MAIL   Вверх
Alexeis
Дата 23.8.2010, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(den1977 @  23.8.2010,  20:36 Найти цитируемый пост)
заметил, что если файл или папка имеют атрибут "только чтение"

  Да, есть такое дело, можно перед удалением вызвать SetFileAttributes(path+sr.name, FILE_ATTRIBUTE_NORMAL)


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
den1977
  Дата 23.8.2010, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 23.8.2010

Репутация: нет
Всего: нет



Цитата(Alexeis @  23.8.2010,  22:43 Найти цитируемый пост)
Да, есть такое дело, можно перед удалением вызвать SetFileAttributes(path+sr.name, FILE_ATTRIBUTE_NORMAL) 


При попытке это использовать получил такую ошибку 
[Pascal Error] Unit1.pas(75): E2010 Incompatible types: 'string' and 'PAnsiChar'

А так прошло - SetFileAttributes(PAnsiChar(path+sr.name), FILE_ATTRIBUTE_NORMAL); - так правильно?


Это сообщение отредактировал(а) den1977 - 23.8.2010, 21:58
PM MAIL   Вверх
Alexeis
Дата 23.8.2010, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(den1977 @  23.8.2010,  20:54 Найти цитируемый пост)
А так прошло

Ну да, все верно, это я ступил. В MSDN также отмечено про read only файлы.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
den1977
  Дата 23.8.2010, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 23.8.2010

Репутация: нет
Всего: нет



Alexeis и Всем большое спасибо за помощь и участие!!!  smile 
Все что хотел получилось !!!  smile 

PS.:
Но может кто все-таки поможет с изначальным вопросм по SHFILEOPSTRUCT  smile 
Теперь уже просто интерестно  smile 


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0967 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.