No borrar una carpeta si contiene archivos no cerrados - página 2

 
Rashid Umarov:

Por alguna razón, el sistema operativo no permite eliminar el archivo - o bien está abierto por otro programa, o no está suficientemente autorizado.

Exactamente así. Cuando intento borrar una carpeta que ya contiene subcarpetas y archivos, primero borro los archivos. Sólo quedan las subcarpetas. Intento limpiarlas usando FolderClean() y luego llamo a FolderDelete(). Sin embargo, el resultado es que aquellas subcarpetas que estaban vacías se borran bien, pero si había más subcarpetas dentro de las subcarpetas no se borran. Después de eso, intento eliminar las carpetas del navegador de archivos en el MetaEditor manualmente, pero el terminal no las elimina y aparece esta ventana:

Hago clic en "Continuar", acepto los cambios, pero la carpeta sigue sin borrarse. Después de cerrar por completo y volver a abrir el terminal, las carpetas que deberían haber sido borradas desaparecen por sí solas o no, pero puedes borrarlas inmediatamente y de forma manual sin la ventana anterior.

Tales rarezas...

 
Vladimir Karputov:

Lo que tenía que probar: el viejo terminal NO VE los programas MQL5. Estás tratando de abrir la caja de arena de archivos de otra persona en el script MQL5.

Las funciones funcionan de forma idéntica en ambos terminales. Se utiliza la caja de arena de archivos del terminal donde se ejecuta el script. Se trata de archivos nativos del terminal en uso. Créeme, esto no es un problema...
 
Rashid Umarov:


PS Y en general - no dar los registros del programa es obligar a otros a adivinar por los posos del café

Echa un vistazo a este gif:



He dado el código para este script arriba, en la página anterior.

 

Debo añadir que las carpetas que estoy intentando borrar primero por software y luego manualmente no se abren por ningún lado. Además, no se pueden abrir en ningún sitio, salvo en el propio navegador de archivos del MetaEditor, porque están vacíos y los archivos de los mismos fueron borrados previamente. Los archivos borrados tampoco se han abierto en ningún sitio.

La ventana que pide la aprobación del administrador para borrar manualmente las carpetas en el navegador de archivos en el MetaEditor sólo aparece cuando se intenta borrar las carpetas que el programa intentó borrar usando FolderClean() y FolderDelete() anteriormente. Esta ventana nunca aparece cuando se intenta eliminar otras carpetas.

 
Реter Konow:

¿Por qué falla la función FolderClean() de este script?

Al intentar limpiar una carpeta se produce el error 5026 - (no se puede limpiar la carpeta).

Este script está tomado de la documentación ( sección de la función FolderDelete()) y ligeramente modificado. Para eliminar completamente una carpeta que contiene otras subcarpetas o archivos, hay que borrarla. Para ello se añade una llamada a FolderClean().

¿Puedo preguntar por qué no se cierra el expediente? ¿O es que no lo veo?

Aquí hay un fragmento de su código desde la apertura del archivo hasta la petición de borrado...

   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:

¿Puedo preguntar por qué no se cierra el expediente? ¿O es que no lo veo?

Aquí hay un fragmento de su código desde la apertura del archivo hasta la pregunta sobre el borrado...

Hasta donde yo sé, si no se han hecho cambios en el archivo usando funciones de archivo (por ejemplo, FileWrite()), no hay necesidad de cerrarlo. La función FileOpen() sólo crea un nuevo archivo y esta operación no requiere el cierre del archivo (la documentación de esta función tampoco dice que el archivo deba cerrarse después de la creación). Además, este script está tomado de la documentación y no he cambiado nada allí. Acabo de añadir líneas con la función FolderClean().
 
Реter Konow:
Hasta donde yo sé, si no se han realizado cambios en el archivo mediante FileWrite(), no es necesario cerrarlo. La función FileOpen() simplemente crea un nuevo archivo y esta operación no requiere cerrar el archivo. Además, este script está sacado de la documentación y no he cambiado nada allí. Acabo de añadir líneas con la función FolderClean().

Pero si miras el código usando el depurador, verás que inmediatamente después de que se ejecute FileOpen(), hay un archivo con tamaño nulo en el disco. Y hay bastantes errores e inexactitudes en la documentación.

 
Alexey Viktorov:

Pero si se revisa el código con el depurador, hay un archivo de tamaño cero en el disco justo después de ejecutar FileOpen(). Y hay bastantes errores e inexactitudes en la documentación.

Así que debería ser de tamaño cero para este ejemplo.

Ahora trataré de cerrar explícitamente el archivo en el script y lo intentaré de nuevo.

 
Реter Konow:

Así que debería ser de tamaño cero para este ejemplo.

Voy a intentar un cierre explícito del archivo en el script y volveré a intentarlo.

Rara vez miro los códigos de muestra, y he borrado la carpeta sin problemas. Así que el 99% está seguro de que ese es el problema.
 

El resultado es el mismo.

Aquí está el nuevo código:

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