0
string userRoot = Environment.GetEnvironmentVariable("USERPROFILE"); 

string paths = string.Format("{0}\\AppData\\Local\\Temp", userRoot); 

DirectoryInfo folder = new DirectoryInfo(paths); 

foreach (FileInfo file in folder.GetFiles()) 

{ 

        file.Delete(); 

} 

foreach (DirectoryInfo dir in folder.GetDirectories()) 

{ 

        dir.Delete(true); 

}

Это мой код: он удаляет всё из папки %temp%

Есть вопрос: при удалении находятся файлы, которые открыты в системных программах. Так вот, можно ли сделать так, чтобы при виде таких файлов c# их просто пропускал?

ciwnat
  • 1
  • 2
    В try/catch оберните. А вообще, если есть такие файлы, и их надо удалить, то стоит подумать о том, как это обойти, например, можно попробовать использовать MoveFileEx с флагом MOVEFILE_DELAY_UNTIL_REBOOT из WinAPI, для того, чтоб пометить файл на удаление после перезагрузки компьютера (пример). Так вот удалять файлы, без ожидания завершения процесса, оставлять следы, ну.. Странное решение. – EvgeniyZ Jun 17 '23 at 17:33
  • Использовать перегрузку GetFiles с параметром new EnumerationOptions { IgnoreInaccessible = true }. PS: лучше использовать метод EnumerateFiles. – Alexander Petrov Jun 17 '23 at 18:06
  • 1
  • Прошу обратить внимание, что Path.GetTempPath - статический метод статического объекта, лучше по возможности избегать применения. – rotabor Jun 17 '23 at 18:33
  • 1
    @rotabor вы написали странное. Почему? А что по поводу Environment.GetEnvironmentVariable? – aepot Jun 18 '23 at 10:17

1 Answers1

0

Можно воспользоваться следующим алгоритмом как одним из вариантов решения:

using System;
using System.IO;
namespace NsSkipFiles {
    class SkipFiles {
        static void DeleteDirectory(DirectoryInfo folder) {
            foreach (FileInfo file in folder.GetFiles()) try { file.Delete(); } catch { }
            foreach (DirectoryInfo dir in folder.GetDirectories()) DeleteDirectory(dir);
            try { folder.Delete(); } catch { }
        }
        static void Main() {
            DeleteDirectory(new DirectoryInfo(
                string.Format("{0}\\AppData\\Local\\Temp"
                    , Environment.GetEnvironmentVariable("USERPROFILE")))); 
        }
    }
}

Метод DeleteDirectory вызывается рекурсивно. В нём сначала удаляются файлы в папке, потом удалятся подпапки рекурсивным вызовом, потом удаляется сама папка. Файлы, которые заблокированы другими приложениями, игнорируются с помощью try catch. Такой алгоритм позволяет избежать случаев, когда удаление всех остальных элементов в папке отменяется из-за наличия одного заблокированного файла или папки.

rotabor
  • 4,251
  • Если folder.Delete упадёт, то не все возможные файлы будут удалены. Здесь рекурсия только решит задачу. https://ru.stackoverflow.com/a/1235165/373567 – aepot Jun 17 '23 at 20:49
  • @aepot folder.Delete вызывается после того, как из этого folder сначала удалены все файлы, а потом все подпапки. И тогда folder.Delete будет успешно выполнен (если папка не заблокирована/есть доступ). То есть задача folder.Delete лишь удалить саму папку (пустую). Таким образом всё, что может быть удалено, будет удалено – rotabor Jun 17 '23 at 21:32
  • Возможно я что-то проглядел, тяжело читать C#, отформатированный как JavaScript, да еще и операндами в одну строку. – aepot Jun 17 '23 at 21:44