diff --git a/Compression.BSA.Test/BSATests.cs b/Compression.BSA.Test/BSATests.cs index 96116f30..ddb2d779 100644 --- a/Compression.BSA.Test/BSATests.cs +++ b/Compression.BSA.Test/BSATests.cs @@ -95,8 +95,7 @@ namespace Compression.BSA.Test { TestContext.WriteLine($"From {bsa}"); TestContext.WriteLine("Cleaning Output Dir"); - if (Directory.Exists(_tempDir)) Directory.Delete(_tempDir, true); - //if (Directory.Exists(ArchiveTempDir)) Directory.Delete(ArchiveTempDir, true); + if (Directory.Exists(_tempDir)) Utils.DeleteDirectory(_tempDir); Directory.CreateDirectory(_tempDir); TestContext.WriteLine($"Reading {bsa}"); diff --git a/Wabbajack.Common/Utils.cs b/Wabbajack.Common/Utils.cs index 05b630dc..c295514f 100644 --- a/Wabbajack.Common/Utils.cs +++ b/Wabbajack.Common/Utils.cs @@ -825,5 +825,48 @@ namespace Wabbajack.Common } return ErrorResponse.Success; } + + /// + /// Both AlphaFS and C#'s Directory.Delete sometimes fail when certain files are read-only + /// or have other weird attributes. This is the only 100% reliable way I've found to completely + /// delete a folder. If you don't like this code, it's unlikely to change without a ton of testing. + /// + /// + public static void DeleteDirectory(string path) + { + var info = new ProcessStartInfo + { + FileName = "cmd.exe", + Arguments = $"/c del /f /q /s \"{path}\" && rmdir /q /s \"{path}\" ", + RedirectStandardError = true, + RedirectStandardInput = true, + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + var p = new Process + { + StartInfo = info + }; + + p.Start(); + ChildProcessTracker.AddProcess(p); + try + { + p.PriorityClass = ProcessPriorityClass.BelowNormal; + } + catch (Exception) + { + } + + while (!p.HasExited) + { + var line = p.StandardOutput.ReadLine(); + if (line == null) break; + Status(line); + } + p.WaitForExit(); + } } } diff --git a/Wabbajack.Lib/ACompiler.cs b/Wabbajack.Lib/ACompiler.cs index 89c3737d..27307871 100644 --- a/Wabbajack.Lib/ACompiler.cs +++ b/Wabbajack.Lib/ACompiler.cs @@ -119,7 +119,7 @@ namespace Wabbajack.Lib Utils.Log("Removing ModList staging folder"); - Directory.Delete(ModListOutputFolder, true); + Utils.DeleteDirectory(ModListOutputFolder); } public void ShowReport() diff --git a/Wabbajack.Lib/MO2Compiler.cs b/Wabbajack.Lib/MO2Compiler.cs index d0ea02ee..4aa808e5 100644 --- a/Wabbajack.Lib/MO2Compiler.cs +++ b/Wabbajack.Lib/MO2Compiler.cs @@ -107,7 +107,7 @@ namespace Wabbajack.Lib UpdateTracker.NextStep("Cleaning output folder"); if (Directory.Exists(ModListOutputFolder)) - Directory.Delete(ModListOutputFolder, true, true); + Utils.DeleteDirectory(ModListOutputFolder); UpdateTracker.NextStep("Finding Install Files"); Directory.CreateDirectory(ModListOutputFolder); diff --git a/Wabbajack.Lib/MO2Installer.cs b/Wabbajack.Lib/MO2Installer.cs index 8874b089..79972d25 100644 --- a/Wabbajack.Lib/MO2Installer.cs +++ b/Wabbajack.Lib/MO2Installer.cs @@ -196,7 +196,7 @@ namespace Wabbajack.Lib if (Directory.Exists(bsaDir)) { Info($"Removing temp folder {Consts.BSACreationDir}"); - Directory.Delete(bsaDir, true, true); + Utils.DeleteDirectory(bsaDir); } } diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index 0ebe03ad..40848240 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -76,7 +76,7 @@ namespace Wabbajack.Lib AddExternalFolder(); Info("Cleaning output folder"); - if (Directory.Exists(ModListOutputFolder)) Directory.Delete(ModListOutputFolder, true); + if (Directory.Exists(ModListOutputFolder)) Utils.DeleteDirectory(ModListOutputFolder); Directory.CreateDirectory(ModListOutputFolder); IEnumerable vortexStagingFiles = Directory.EnumerateFiles(StagingFolder, "*", SearchOption.AllDirectories) diff --git a/Wabbajack.Test/EndToEndTests.cs b/Wabbajack.Test/EndToEndTests.cs index d08f3e22..9fe17c98 100644 --- a/Wabbajack.Test/EndToEndTests.cs +++ b/Wabbajack.Test/EndToEndTests.cs @@ -69,7 +69,7 @@ namespace Wabbajack.Test var loot_folder = Path.Combine(utils.InstallFolder, "LOOT Config Files"); if (Directory.Exists(loot_folder)) - Directory.Delete(loot_folder, true); + Utils.DeleteDirectory(loot_folder); var compiler = new MO2Compiler(utils.InstallFolder); compiler.MO2DownloadsFolder = Path.Combine(utils.DownloadsFolder); diff --git a/Wabbajack.Test/TestUtils.cs b/Wabbajack.Test/TestUtils.cs index 3934e21e..2020a40f 100644 --- a/Wabbajack.Test/TestUtils.cs +++ b/Wabbajack.Test/TestUtils.cs @@ -113,7 +113,7 @@ namespace Wabbajack.Test public void Dispose() { var exts = new [] {".md", ".exe"}; - Directory.Delete(Path.Combine(WorkingDirectory, ID), true); + Utils.DeleteDirectory(Path.Combine(WorkingDirectory, ID)); Profiles.Do(p => { foreach (var ext in exts) { diff --git a/Wabbajack.VirtualFileSystem.Test/VirtualFileSystemTests.cs b/Wabbajack.VirtualFileSystem.Test/VirtualFileSystemTests.cs index 3b404c81..6d3c73ba 100644 --- a/Wabbajack.VirtualFileSystem.Test/VirtualFileSystemTests.cs +++ b/Wabbajack.VirtualFileSystem.Test/VirtualFileSystemTests.cs @@ -24,7 +24,7 @@ namespace Wabbajack.VirtualFileSystem.Test { Utils.LogMessages.Subscribe(f => TestContext.WriteLine(f)); if (Directory.Exists(VFS_TEST_DIR)) - Directory.Delete(VFS_TEST_DIR, true); + Utils.DeleteDirectory(VFS_TEST_DIR); Directory.CreateDirectory(VFS_TEST_DIR); Queue = new WorkQueue(); context = new Context(Queue); @@ -205,7 +205,7 @@ namespace Wabbajack.VirtualFileSystem.Test { var path = Path.Combine(VFS_TEST_DIR, folder); ZipFile.CreateFromDirectory(path, Path.Combine(VFS_TEST_DIR, output)); - Directory.Delete(path, true); + Utils.DeleteDirectory(path); } } -} \ No newline at end of file +} diff --git a/Wabbajack.VirtualFileSystem/Context.cs b/Wabbajack.VirtualFileSystem/Context.cs index f3a35402..243e3abd 100644 --- a/Wabbajack.VirtualFileSystem/Context.cs +++ b/Wabbajack.VirtualFileSystem/Context.cs @@ -227,7 +227,7 @@ namespace Wabbajack.VirtualFileSystem paths.Do(p => { if (Directory.Exists(p)) - Directory.Delete(p, true, true); + Utils.DeleteDirectory(p); }); }; } @@ -417,7 +417,7 @@ namespace Wabbajack.VirtualFileSystem public void Dispose() { - Directory.Delete(FullName, true, true); + Utils.DeleteDirectory(FullName); } } }