Una cartella non viene cancellata se contiene file non chiusi - pagina 2

 
Rashid Umarov:

Per qualche motivo, il sistema operativo non permette di cancellare il file - o è aperto da un altro programma, o non è abbastanza autorizzato.

Esattamente così. Quando cerco di eliminare una cartella che contiene già sottocartelle e file, elimino prima i file. Rimangono solo le sottocartelle. Provo a pulirli usando FolderClean() e poi chiamo FolderDelete(). Tuttavia, il risultato è che quelle sottocartelle che erano vuote sono ben cancellate, ma se c'erano più sottocartelle all'interno delle sottocartelle non vengono cancellate. Dopo di che, provo a rimuovere manualmente le cartelle dal navigatore di file in MetaEditor, ma il terminale non le rimuove e fa apparire questa finestra:

Clicco su "Continua", accetto le modifiche, ma la cartella non viene ancora cancellata. Dopo aver chiuso completamente e riaperto il terminale, le cartelle che avrebbero dovuto essere cancellate scompaiono da sole oppure no, ma è possibile cancellarle immediatamente e manualmente senza la finestra di cui sopra.

Tali stranezze...

 
Vladimir Karputov:

Quello che ho dovuto provare: il vecchio terminale NON VEDE i programmi MQL5. Stai cercando di aprire il file sandbox di qualcun altro nello script MQL5.

Le funzioni funzionano in modo identico su entrambi i terminali. Viene utilizzato il file sandbox del terminale dove lo script è in esecuzione. Questi sono file nativi del terminale in uso. Credetemi, non è assolutamente questo il problema...
 
Rashid Umarov:


PS E in generale - non dare i log del programma è costringere gli altri a indovinare dai fondi di caffè

Date un'occhiata a questa gif:



Ho dato il codice per questo script sopra, nella pagina precedente.

 

Dovrei aggiungere che le cartelle che sto cercando di cancellare prima software e poi manualmente non sono aperte da nessuna parte. Inoltre, non possono essere aperti da nessuna parte eccetto il navigatore di file stesso in MetaEditor, perché sono vuoti e i file da loro sono stati precedentemente cancellati. Anche i file cancellati non sono stati aperti da nessuna parte.

La finestra che chiede l'approvazione dell'amministratore per cancellare manualmente le cartelle nel navigatore di file in MetaEditor appare solo quando si cerca di cancellare quelle cartelle che il programma ha cercato di cancellare usando FolderClean() e FolderDelete() in precedenza. Questa finestra non appare mai quando si cerca di cancellare altre cartelle.

 
Реter Konow:

Perché la funzione FolderClean() in questo script fallisce?

Il tentativo di pulire una cartella dà come risultato l'errore 5026 - (la cartella non può essere pulita).

Questo script è preso dalla documentazione ( sezione della funzione FolderDelete()) e leggermente modificato. Per eliminare completamente una cartella che contiene altre sottocartelle o file, dovete cancellarla. Viene aggiunta una chiamata a FolderClean() per questo scopo.

Posso chiedere perché non c'è la chiusura del file? O sono io che non lo vedo?

Ecco un frammento del tuo codice dall'apertura del file alla richiesta di cancellazione...

   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:

Posso chiedere perché non c'è la chiusura del file? O sono io che non lo vedo?

Ecco un frammento del tuo codice dall'apertura del file alla domanda sulla cancellazione...

Per quanto ne so, se non sono state apportate modifiche al file utilizzando funzioni di file (ad esempio FileWrite()), non c'è bisogno di chiuderlo. La funzione FileOpen() crea semplicemente un nuovo file e questa operazione non richiede la chiusura del file (anche la documentazione di questa funzione non dice che il file deve essere chiuso dopo la creazione). Inoltre, questo script è preso dalla documentazione e non ho cambiato nulla lì. Ho appena aggiunto delle linee con la funzione FolderClean().
 
Реter Konow:
Per quanto ne so, se non sono state fatte modifiche al file usando FileWrite(), non c'è bisogno di chiuderlo. La funzione FileOpen() crea semplicemente un nuovo file e questa operazione non richiede la chiusura del file. Inoltre, questo script è preso dalla documentazione e non ho cambiato nulla lì. Ho appena aggiunto delle linee con la funzione FolderClean().

Ma se guardate il codice usando il debugger, vedrete che subito dopo l'esecuzione di FileOpen(), c'è un file di dimensioni nulle sul disco. E ci sono piuttosto molti errori e imprecisioni nella documentazione.

 
Alexey Viktorov:

Ma se esaminate il codice con il debugger, c'è un file di dimensioni zero sul disco subito dopo l'esecuzione di FileOpen(). E ci sono piuttosto molti errori e imprecisioni nella documentazione.

Quindi dovrebbe essere di dimensioni zero per questo esempio.

Ora proverò a chiudere esplicitamente il file nello script e riprovare.

 
Реter Konow:

Quindi dovrebbe essere di dimensioni zero per questo esempio.

Proverò a fare in modo che lo script chiuda esplicitamente il file e riproverò.

Guardo raramente i codici di esempio e ho cancellato la cartella senza problemi. Quindi al 99% è sicuro che sia questo il problema.
 

Il risultato è lo stesso.

Ecco il nuovo codice:

//+------------------------------------------------------------------+ 
//|                                            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("Удаление отменено"); 
//--- 
  }
Motivazione: