Не удаляется папка, если в ней есть незакрытые файлы - страница 2

 
Rashid Umarov:

По какой-то причину операционная система не дает удалить файл - то ли он открыт другой программой, то ли прав не хватает.

Именно так. Когда я пытаюсь удалить папку уже содержащую подпапки и файлы, то сначала удаляю файлы. Остаются только подпапки. Их пытаюсь очистить с помощью FolderClean() и потом вызываю FolderDelete(). Однако, в результате те подпапки которые были пусты хорошо удаляются, но если внутри подпапок были еще подпапки - они не удаляются. После этого, я пытаюсь удалить папки из файлового навигатора в MetaEditor вручную, но терминал их не удаляет и выскакивает это окно:

Нажимаю на "Continue", соглашаюсь на изменения, но папка все равно не стирается. После полного закрытия и повторного открытия терминала, папки которые должны были быть стерты либо сами исчезают, либо нет, но при этом их уже можно сразу стереть вручную без вышеприведенного окна.

Вот такие странности...

 
Vladimir Karputov:

Что и требовалось доказать: старый терминал НЕ ВИДИТ MQL5 программы. Вы в MQL5 скрипте пытаетесь открыть чужую файловую песочницу. 

Функции работают идентично на обоих терминалах. Используется Файловая песочница того терминала, на котором работает скрипт. Это родные файлы того терминала, который используется. Поверьте, в этом точно нет проблемы...
 
Rashid Umarov:


PS И вообще - не давать логи программы - это заставлять других гадать на кофейной гуще

Вот посмотрите на этот гиф:



Код этого скрипта я привел выше, на прошлой странице.

 

Добавлю, что папки которые пытаюсь стереть сначала программно и потом вручную нигде не открыты. Более того, они не могут быть где то открыты кроме самого файлового навигатора в Метаэдитор, поскольку они пусты и файлы из них были до этого стерты. Стертые файлы тоже не были нигде открыты.

Окно с требованием подтверждения администратора для стирания папок вручную в файловом навигаторе в метаэдитор, возникает только при попытке стереть те папки, которые программа пыталась удалить с помощью функций FolderClean() и  FolderDelete() ранее. При попытке удаления других папок это окно никогда не появляется.

 
Реter Konow:

Почему не срабатывает функция FolderClean() вот в этом скрипте:  ?

В результате попытки очищения папки, выдает ошибку 5026 - (папка не может быть очищена).

Данный скрипт взят из документации (раздел функции FolderDelete()) и слегка модифицирован. Для полного удаления папки, которая содержит в себе другие подпапки или файлы необходимо ее очистить. Для этого добавлен вызов функции FolderClean().

А можно поинтересоваться почему нет закрытия файла? Или я просто не вижу?

Вот фрагмент Вашего кода от открытия файла до вопроса об удалении...

   handle=FileOpen(filepath,FILE_WRITE|FILE_TXT); // флаг FILE_WRITE в данном случае обязателен, см. справку к функции FileOpen 
   if(handle!=INVALID_HANDLE) 
      PrintFormat("Открыли файл на чтение %s",working_folder+"\\"+filepath); 
   else 
      PrintFormat("Не удалось создать файл %s в папке %s. Код ошибки=",filename,secondFolder, GetLastError());
 
   Comment(StringFormat("Готовимся удалить папки %s и %s", firstFolder, secondFolder)); 
//--- Небольшая пауза в 5 секунд, чтобы мы могли прочитать сообщение на графике 
   Sleep(5000); // Sleep() нельзя использовать в индикаторах!
 
//--- выведем диалоговое окно и просим пользователя 
 
Alexey Viktorov:

А можно поинтересоваться почему нет закрытия файла? Или я просто не вижу?

Вот фрагмент Вашего кода от открытия файла до вопроса об удалении...

Насколько я знаю, если в файл не вносились изменения с помощью файловых функций  (например FileWrite()), то закрывать его не нужно. Функция FileOpen() просто создает новый файл и эта операция не требует закрытия файла (в документации по этой функции, тоже не говорится, что файл нужно после создания закрывать). К тому же этот скрипт взят из документации и я там ничего не правил. Только добавил строки с функцией FolderClean().
 
Реter Konow:
Насколько я знаю, если в файл не вносились изменения с помощью функции  FileWrite(), то закрывать его не нужно. Функция FileOpen() просто создает новый файл и эта операция не требует закрытия файла. К тому же этот скрипт взят из документации и я там ничего не правил. Только добавил строки с функцией FolderClean().

Но если пройти по коду отладчиком, то сразу после выполнения FileOpen() на диске присутствует файл нулевого размера. А в документации ошибок и неточностей достаточно много.

 
Alexey Viktorov:

Но если пройти по коду отладчиком, то сразу после выполнения FileOpen() на диске присутствует файл нулевого размера. А в документации ошибок и неточностей достаточно много.

Так он и должен быть нулевого размера для этого примера.

Сейчас попробую внести в скрипт явное закрытие файла и попробую еще раз.

 
Реter Konow:

Так он и должен быть нулевого размера для этого примера.

Сейчас попробую внести в скрипт явное закрытие файла и попробую еще раз.

Я редко смотрю образцы кодов, и удаление папки проделывал без проблем. Так-что на 99% уверен что проблема именно в этом.
 

Результат тот же.

Вот новый код:

//+------------------------------------------------------------------+ 
//|                                            Demo_FolderDelete.mq5 | 
//|                        Copyright 2011, MetaQuotes Software Corp. | 
//|                                              https://www.mql5.com | 
//+------------------------------------------------------------------+ 
#property copyright "Copyright 2011, MetaQuotes Software Corp." 
#property link      "https://www.mql5.com" 
#property version   "1.00" 
//--- описание 
#property description "Скрипт показывает пример использования FolderDelete()." 
#property description "Сначала создаются две папки, одна пустая, другая содержит файл." 
#property description "При попытке удаления непустой папки получим ошибку и предупреждение."
 
//--- покажем окно входных параметров при запуске скрипта 
#property script_show_inputs 
//--- входные параметры 
input string   firstFolder="empty";    // пустая папка 
input string   secondFolder="nonempty";// папка, в которой будет один файл 
string filename="delete_me.txt";       // имя файла, который мы создадим в папке secondFolder 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart() 
  { 
//--- хендл файла запишем сюда 
   int handle; 
//--- выясним в какой папке мы работаем 
   string working_folder=TerminalInfoString(TERMINAL_DATA_PATH)+"\\MQL4\\Files"; 
//--- отладочное сообщение    
   PrintFormat("working_folder=%s",working_folder); 
//--- попытка создать пустую папку относительно пути MQL4\Files 
   if(FolderCreate(firstFolder,0)) // 0 означает, что работаем в локальной папке терминала 
     { 
      //--- выведем полный путь до созданной папки 
      PrintFormat("Cоздали папку %s",working_folder+"\\"+firstFolder); 
      //--- сбросим код ошибки 
      ResetLastError(); 
     } 
   else 
      PrintFormat("Не удалось создать папку %s. Код ошибки %d",working_folder+"\\"+firstFolder, GetLastError());
 
//--- теперь создадим непустую папку с помощью функции FileOpen() 
   string filepath=secondFolder+"\\"+filename;  // сформируем путь для файла, который хотим открыть на запись в несуществующей папке 
   handle=FileOpen(filepath,FILE_WRITE|FILE_TXT); // флаг FILE_WRITE в данном случае обязателен, см. справку к функции FileOpen 
   if(handle!=INVALID_HANDLE) 
     {
//*************************************************************************     
   //---- Явно закрываем файл.   
      FileClose(handle);
//*************************************************************************           
      PrintFormat("Открыли файл на чтение %s",working_folder+"\\"+filepath); 
     } 
   else 
      PrintFormat("Не удалось создать файл %s в папке %s. Код ошибки=",filename,secondFolder, GetLastError());
 
   Comment(StringFormat("Готовимся удалить папки %s и %s", firstFolder, secondFolder)); 
//--- Небольшая пауза в 5 секунд, чтобы мы могли прочитать сообщение на графике 
   Sleep(5000); // Sleep() нельзя использовать в индикаторах!
 
//--- выведем диалоговое окно и просим пользователя 
   int choice=MessageBox(StringFormat("Удалить папки %s и %s?", firstFolder, secondFolder), 
                         "Удаление папок", 
                         MB_YESNO|MB_ICONQUESTION); //  будут две кнопки - "Yes" и "No"
 
//--- выполним действия в зависимости от выбранного варианта 
   if(choice==IDYES) 
     { 
      //--- очистим комментарий на графике 
      Comment(""); 
      //--- выведем сообщение в журнал "Эксперты" 
      PrintFormat("Пробуем удалить папки %s и %s",firstFolder, secondFolder); 
      ResetLastError(); 
      //--- удаляем пустую папку 
      if(FolderDelete(firstFolder)) 
         //--- должны увидеть это сообщение, так как папка пустая 
         PrintFormat("Папка %s успешно удалена",firstFolder); 
      else 
         PrintFormat("Не удалось удалить папку %s. Код ошибки=%d", firstFolder, GetLastError());
 
      ResetLastError(); 

   //***********************************************************************************************************************   
      //--- сначала очищаем папку
      if(FolderClean(secondFolder))
         PrintFormat("Папка %s успешно очищена", secondFolder);
      else 
         //---  
         PrintFormat("Не удалось очистить папку %s. Код ошибки=%d", secondFolder, GetLastError());
   //***********************************************************************************************************************   
   
      ResetLastError(); 
        
      //--- удаляем папку, которая содержит файл               
      if(FolderDelete(secondFolder)) 
         PrintFormat("Папка %s успешно удалена", secondFolder); 
      else 
         //--- 
         PrintFormat("Не удалось удалить папку %s. Код ошибки=%d", secondFolder, GetLastError()); 
     }  

   else 
      Print("Удаление отменено"); 
//--- 
  }