// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-iterate-through-a-directory-tree private static IEnumerable <FileInfo> TraverseTree(string root, Func <string, bool> dirValidator = null) { if (dirValidator == null) { dirValidator = s => true; } Stack <string> dirs = new Stack <string>(32); if (!Directory.Exists(root)) { throw new ArgumentException(); } dirs.Push(root); while (dirs.Count > 0) { string currentDir = dirs.Pop(); string[] subDirs; try { subDirs = Directory.GetDirectories(currentDir); } catch (UnauthorizedAccessException) { continue; } catch (DirectoryNotFoundException) { continue; } string[] files; try { files = Directory.GetFiles(currentDir); } catch (UnauthorizedAccessException) { continue; } catch (DirectoryNotFoundException) { continue; } foreach (string str in subDirs) { if (dirValidator(str)) { dirs.Push(str); } } foreach (string file in files) { FileInfo nextValue; try { nextValue = new FileInfo(file); } catch (FileNotFoundException) { continue; } yield return(nextValue); } } }
private static void InstallPendingModUpdates() { var pendingDir = Path.Combine(BeatSaber.InstallPath, "IPA", "Pending"); if (!Directory.Exists(pendingDir)) { return; } // there are pending updates, install updater.Info("Installing pending updates"); var toDelete = new string[0]; var delFn = Path.Combine(pendingDir, DeleteFileName); if (File.Exists(delFn)) { toDelete = File.ReadAllLines(delFn); File.Delete(delFn); } foreach (var file in toDelete) { try { File.Delete(Path.Combine(BeatSaber.InstallPath, file)); } catch (Exception e) { updater.Error("While trying to install pending updates: Error deleting file marked for deletion"); updater.Error(e); } } #region Self Protection string path; if (Directory.Exists(path = Path.Combine(pendingDir, "IPA"))) { var dirs = new Stack <string>(20); dirs.Push(path); while (dirs.Count > 0) { var currentDir = dirs.Pop(); string[] subDirs; string[] files; try { subDirs = Directory.GetDirectories(currentDir); files = Directory.GetFiles(currentDir); } catch (UnauthorizedAccessException e) { updater.Error(e); continue; } catch (DirectoryNotFoundException e) { updater.Error(e); continue; } foreach (var file in files) { try { if (!Utils.GetRelativePath(file, path).Split(Path.PathSeparator).Contains("Pending")) { File.Delete(file); } } catch (FileNotFoundException e) { updater.Error(e); } } foreach (var str in subDirs) { dirs.Push(str); } } } if (File.Exists(path = Path.Combine(pendingDir, "IPA.exe"))) { File.Delete(path); if (File.Exists(path = Path.Combine(pendingDir, "Mono.Cecil.dll"))) { File.Delete(path); } } #endregion try { Utils.CopyAll(new DirectoryInfo(pendingDir), new DirectoryInfo(BeatSaber.InstallPath), onCopyException: (e, f) => { updater.Error($"Error copying file {Utils.GetRelativePath(f.FullName, pendingDir)} from Pending:"); updater.Error(e); return(true); }); } catch (Exception e) { updater.Error("While trying to install pending updates: Error copying files in"); updater.Error(e); } try { Directory.Delete(pendingDir, true); } catch (Exception e) { updater.Error("Something went wrong performing an operation that should never fail!"); updater.Error(e); } }