Não apagar uma pasta se ela contiver arquivos não fechados - página 2

 
Rashid Umarov:

Por algum motivo, o sistema operacional não permite excluir o arquivo - ou ele é aberto por outro programa, ou não é suficientemente autorizado.

Exatamente como isto. Quando tento apagar uma pasta que já contém subpastas e arquivos, eu apago os arquivos primeiro. Restam apenas as subpastas. Eu tento limpá-los usando FolderClean() e depois chamo FolderDelete(). Entretanto, o resultado é que aquelas subpastas que estavam vazias são bem apagadas, mas se houvesse mais subpastas dentro das subpastas, elas não são apagadas. Depois disso, tento remover as pastas do navegador de arquivos no MetaEditor manualmente, mas o terminal não as remove e abre esta janela:

Eu clico em "Continuar", concordo com as mudanças, mas a pasta ainda não foi apagada. Após fechar e reabrir completamente o terminal, as pastas que deveriam ter sido apagadas desaparecem por si mesmas ou não, mas você pode apagá-las imediatamente e manualmente sem a janela acima.

Tais curiosidades...

 
Vladimir Karputov:

O que eu tinha que provar: o terminal antigo NÃO VÊ programas MQL5. Você está tentando abrir a caixa de areia do arquivo de outra pessoa no script MQL5.

As funções funcionam de forma idêntica em ambos os terminais. É utilizada a caixa de areia do terminal onde o roteiro está sendo executado. Estes são arquivos nativos do terminal em uso. Acreditem, este não é definitivamente o problema...
 
Rashid Umarov:


PS E em geral - não dar os logs do programa é forçar outros a adivinhar pela borra de café

Dê uma olhada neste gif:



Eu dei o código para este script acima, na página anterior.

 

Devo acrescentar que as pastas que estou tentando apagar primeiro o software e depois manualmente não estão abertas em nenhum lugar. Além disso, eles não podem ser abertos em nenhum lugar, exceto no MetaEditor, porque estão vazios e os arquivos deles foram apagados anteriormente. Os arquivos apagados também não foram abertos em nenhum lugar.

A janela pedindo aprovação do administrador para apagar manualmente as pastas no navegador de arquivos no MetaEditor só aparece quando se tenta apagar as pastas que o programa tentou apagar usando FolderClean() e FolderDelete() mais cedo. Esta janela nunca aparece quando se tenta apagar outras pastas.

 
Реter Konow:

Por que a função FolderClean() neste script falha?

A tentativa de limpar uma pasta resulta em erro 5026 - (pasta não pode ser limpa).

Este script é retirado da seção de documentação (FolderDelete() function section) e ligeiramente modificado. Para apagar completamente uma pasta que contenha outras subpastas ou arquivos, você tem que limpá-la. Uma chamada para FolderClean() é acrescentada para este fim.

Posso perguntar por que não há um fechamento de arquivo? Ou eu simplesmente não estou vendo?

Aqui está um trecho de seu código desde a abertura do arquivo até o pedido de exclusão...

   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 perguntar por que não há um fechamento do arquivo? Ou eu simplesmente não estou vendo?

Aqui está um trecho de seu código desde a abertura do arquivo até a pergunta sobre a eliminação...

Tanto quanto sei, se nenhuma alteração foi feita no arquivo usando funções de arquivo (por exemplo, FileWrite()), não há necessidade de fechá-lo. A função FileOpen() apenas cria um novo arquivo e esta operação não requer o fechamento do arquivo (a documentação para esta função também não diz que o arquivo deve ser fechado após a criação). Além disso, este roteiro é retirado da documentação e eu não mudei nada lá. Acabei de acrescentar linhas com a função FolderClean().
 
Реter Konow:
Tanto quanto sei, se não foram feitas mudanças no arquivo usando FileWrite(), não há necessidade de fechá-lo. A função FileOpen() simplesmente cria um novo arquivo e esta operação não requer o fechamento do arquivo. Além disso, este roteiro é retirado da documentação e eu não mudei nada lá. Acabei de acrescentar linhas com a função FolderClean().

Mas se você olhar através do código usando o depurador, você verá que imediatamente após FileOpen() ser executado, há um arquivo com tamanho nulo em disco. E há muitos erros e imprecisões na documentação.

 
Alexey Viktorov:

Mas se você passar o código com o depurador, há um arquivo de tamanho zero no disco logo após FileOpen() ser executado. E há muitos erros e imprecisões na documentação.

Portanto, o tamanho deve ser zero para este exemplo.

Agora vou tentar fechar explicitamente o arquivo no roteiro e tentar novamente.

 
Реter Konow:

Portanto, o tamanho deve ser zero para este exemplo.

Vou tentar um arquivo explícito fechado no roteiro e tentar novamente.

Raramente olho para códigos de amostra e excluí a pasta sem nenhum problema. Portanto, 99% de certeza que esse é o problema.
 

O resultado é o mesmo.

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