From df70ce0584133e328d0eb706dec2bc166f38b4f8 Mon Sep 17 00:00:00 2001 From: rdavidek Date: Sun, 1 Mar 2026 17:21:57 +0100 Subject: [PATCH] fixed file deletion in windows --- .../kfmanager/service/FileOperations.java | 48 +++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/src/main/java/cz/kamma/kfmanager/service/FileOperations.java b/src/main/java/cz/kamma/kfmanager/service/FileOperations.java index 19653b6..dcbde79 100644 --- a/src/main/java/cz/kamma/kfmanager/service/FileOperations.java +++ b/src/main/java/cz/kamma/kfmanager/service/FileOperations.java @@ -17,6 +17,7 @@ import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.DosFileAttributeView; import java.nio.file.attribute.PosixFilePermission; import java.util.ArrayList; import java.util.HashSet; @@ -343,22 +344,53 @@ public class FileOperations { private static void deleteDirectoryInternal(Path path) throws IOException { if (Files.isSymbolicLink(path)) { - Files.delete(path); + deletePathWithForce(path); return; } Files.walkFileTree(path, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); + deletePathWithForce(file); return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - Files.delete(dir); + deletePathWithForce(dir); return FileVisitResult.CONTINUE; } }); } + + private static void deletePathWithForce(Path path) throws IOException { + try { + Files.delete(path); + return; + } catch (AccessDeniedException e) { + clearDeletionBlockingAttributes(path); + } + Files.delete(path); + } + + private static void clearDeletionBlockingAttributes(Path path) { + try { + File file = path.toFile(); + if (!file.canWrite()) { + file.setWritable(true); + } + } catch (Exception ignore) {} + + if (cz.kamma.kfmanager.MainApp.CURRENT_OS != cz.kamma.kfmanager.MainApp.OS.WINDOWS) { + return; + } + + try { + DosFileAttributeView dos = Files.getFileAttributeView(path, DosFileAttributeView.class, LinkOption.NOFOLLOW_LINKS); + if (dos != null) { + dos.setReadOnly(false); + dos.setSystem(false); + } + } catch (Exception ignore) {} + } /** * Move files/directories to target directory @@ -494,7 +526,7 @@ public class FileOperations { if (callback != null) { callback.onProgress(currentItem[0], totalItems, file.getName()); } - Files.delete(file.toPath()); + deletePathWithForce(file.toPath()); } else if (file.isDirectory()) { deleteDirectory(file.toPath(), totalItems, currentItem, callback); } else { @@ -502,7 +534,7 @@ public class FileOperations { if (callback != null) { callback.onProgress(currentItem[0], totalItems, file.getName()); } - Files.delete(file.toPath()); + deletePathWithForce(file.toPath()); } break; } catch (IOException e) { @@ -615,7 +647,7 @@ public class FileOperations { if (callback != null) { callback.onProgress(currentItem[0], totalItems, directory.getFileName().toString()); } - Files.delete(directory); + deletePathWithForce(directory); return; } Files.walkFileTree(directory, new SimpleFileVisitor() { @@ -627,7 +659,7 @@ public class FileOperations { if (callback != null) { callback.onProgress(currentItem[0], totalItems, file.getFileName().toString()); } - Files.delete(file); + deletePathWithForce(file); return FileVisitResult.CONTINUE; } catch (IOException e) { if (callback != null) { @@ -650,7 +682,7 @@ public class FileOperations { if (callback != null) { callback.onProgress(currentItem[0], totalItems, dir.getFileName().toString()); } - Files.delete(dir); + deletePathWithForce(dir); return FileVisitResult.CONTINUE; } catch (IOException e) { if (callback != null) {