private async Task InstallManualGameFiles() { if (!ModList.Directives.Any(d => d.To.StartsWith(Consts.ManualGameFilesDir))) { return; } var result = await Utils.Log(new YesNoIntervention("Some mods from this ModList must be installed directly into " + "the game folder. Do you want to do this manually or do you want Wabbajack " + "to do this for you?", "Move mods into game folder?")).Task; if (result != ConfirmationIntervention.Choice.Continue) { return; } var manualFilesDir = Path.Combine(OutputFolder, Consts.ManualGameFilesDir); var gameFolder = GameInfo.GameLocation(); Info($"Copying files from {manualFilesDir} " + $"to the game folder at {gameFolder}"); if (!Directory.Exists(manualFilesDir)) { Info($"{manualFilesDir} does not exist!"); return; } await Directory.EnumerateDirectories(manualFilesDir).PMap(Queue, dir => { var dirInfo = new DirectoryInfo(dir); dirInfo.GetDirectories("*", SearchOption.AllDirectories).Do(d => { var destPath = d.FullName.Replace(manualFilesDir, gameFolder); Status($"Creating directory {destPath}"); Directory.CreateDirectory(destPath); }); dirInfo.GetFiles("*", SearchOption.AllDirectories).Do(f => { var destPath = f.FullName.Replace(manualFilesDir, gameFolder); Status($"Copying file {f.FullName} to {destPath}"); try { File.Copy(f.FullName, destPath); } catch (Exception) { Info($"Could not copy file {f.FullName} to {destPath}. The file may already exist, skipping..."); } }); }); }
private void ProcessDirectory([NotNull] DirectoryInfo droppedDir) { if ((droppedDir.Attributes & FileAttributes.Directory) != FileAttributes.Directory) { Logger.Error($"{droppedDir.FullName} is not a directory, CONTACT DEV TEAM."); return; } foreach (FileInfo subFile in droppedDir.GetFiles()) { ProcessUnknown(subFile); } foreach (DirectoryInfo subFile in droppedDir.GetDirectories()) { ProcessDirectory(subFile); } }
static void RemoveReadonlyAttribute(Alphaleonis.Win32.Filesystem.DirectoryInfo dirInfo) { if ((dirInfo.Attributes & System.IO.FileAttributes.ReadOnly) == System.IO.FileAttributes.ReadOnly) { dirInfo.Attributes = System.IO.FileAttributes.Normal; } foreach (var fi in dirInfo.GetFiles()) { if ((fi.Attributes & System.IO.FileAttributes.ReadOnly) == System.IO.FileAttributes.ReadOnly) { fi.Attributes = System.IO.FileAttributes.Normal; } } foreach (var di in dirInfo.GetDirectories()) { RemoveReadonlyAttribute(di); } return; }
public override DirectoryInfoBase[] GetDirectories() { return(instance.GetDirectories().WrapDirectories(FileSystem)); }
public static int CopyTo(this DirectoryInfo sourceDirectory, DirectoryInfo destinationDirectory, bool copySubDirectories = true, IEnumerable<Predicate<FileInfo>> filesToExclude = null, IEnumerable<string> directoriesToExclude = null) { var copiedItems = 0; if (sourceDirectory == null) { throw new ArgumentNullException(nameof(sourceDirectory)); } if (destinationDirectory == null) { throw new ArgumentNullException(nameof(destinationDirectory)); } if (!sourceDirectory.Exists) { throw new DirectoryNotFoundException( $"Source directory does not exist or could not be found: {sourceDirectory.FullName}"); } var filePredicates = filesToExclude ?? new List<Predicate<FileInfo>>(); var excludedDirectories = directoriesToExclude ?? new List<string>(); if (destinationDirectory.Exists) { if (!destinationDirectory.IsEmpty()) { var fileCount = destinationDirectory.GetFiles().Length; var directoryCount = destinationDirectory.GetDirectories().Length; throw new IOException( $"The folder '{destinationDirectory.FullName}' cannot be used as a target folder since there are {fileCount} files and {directoryCount} folders in the folder"); } } else { destinationDirectory.Create(); copiedItems++; } var files = sourceDirectory.EnumerateFiles().Where(file => filePredicates.All(predicate => !predicate(file))).ToList(); foreach (FileInfo file in files) { var temppath = Path.Combine(destinationDirectory.FullName, file.Name); Debug.WriteLine($"Copying file '{file.Name}' to '{temppath.FullName}'"); file.CopyTo(temppath.FullName, false); copiedItems++; } if (copySubDirectories) { DirectoryInfo[] subDirectory = sourceDirectory.GetDirectories(); foreach (DirectoryInfo subdir in subDirectory) { if ( !excludedDirectories.Any( excluded => subdir.Name.Equals(excluded, StringComparison.InvariantCultureIgnoreCase))) { var subDirectoryTempPath = Path.Combine(destinationDirectory.FullName, subdir.Name); var subDirectoryInfo = new DirectoryInfo(subDirectoryTempPath.FullName); Debug.WriteLine($"Copying directory '{subDirectoryInfo.Name}' to '{subDirectoryTempPath.FullName}'"); copiedItems += subdir.CopyTo(subDirectoryInfo, copySubDirectories, filesToExclude, directoriesToExclude); } } } return copiedItems; }
private DirectorySearchStatusTypes CheckIfDirectoryEmpty(DirectoryInfo startDir, Int32 depth) { if (this.PossibleEndlessLoop > this.Data.InfiniteLoopDetectionCount) { this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(startDir.FullName, DirectorySearchStatusTypes.Error, "Aborted - possible infinite-loop detected")); return(DirectorySearchStatusTypes.Error); } try { if (this.Data.MaxDepth != -1 && depth > this.Data.MaxDepth) { return(DirectorySearchStatusTypes.NotEmpty); } // Cancel process if the user hits stop if (this.CancellationPending) { return(DirectorySearchStatusTypes.NotEmpty); } this.FolderCount++; // update status progress bar after 100 steps: if (this.FolderCount % 100 == 0) { this.ReportProgress(this.FolderCount, $"Checking directory: {startDir.Name}"); } var containsFiles = false; // Get file list IEnumerable <FileInfo> fileList; // some directories could trigger a exception: try { fileList = startDir.EnumerateFiles(); } catch { fileList = null; } if (fileList == null) { // CF = true = folder does not get deleted: containsFiles = true; // secure way this.Data.AddLogMessage("Failed to access files in \"" + startDir.FullName + "\""); this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(startDir.FullName, DirectorySearchStatusTypes.Error, "Failed to access files")); } else { // loop trough files and cancel if containsFiles == true for (var f = 0; f < fileList.Length && !containsFiles; f++) { FileInfo file; Int32 filesize; try { file = fileList[f]; filesize = ( Int32 )file.Length; } catch { // keep folder if there is a strange file that // triggers a exception: return(DirectorySearchStatusTypes.NotEmpty); } // If only one file is good, then stop. if (!SystemFunctions.MatchesIgnorePattern(file, filesize, this.Data.IgnoreEmptyFiles, this.ignoreFileList, out _)) { containsFiles = true; } } } // If the folder does not contain any files -> get subfolders: DirectoryInfo[] subFolderList; try { subFolderList = startDir.GetDirectories(); } catch { // If we can not read the folder -> don't delete it: this.Data.AddLogMessage("Failed to access subdirectories in \"" + startDir.FullName + "\""); this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(startDir.FullName, DirectorySearchStatusTypes.Error, "Failed to access subdirectories")); return(DirectorySearchStatusTypes.Error); } // The folder is empty, break here: if (!containsFiles && !subFolderList.Any()) { return(DirectorySearchStatusTypes.Empty); } var allSubDirectoriesEmpty = true; foreach (var curDir in subFolderList) { var attribs = curDir.Attributes; // Hidden folder? var ignoreSubDirectory = this.Data.IgnoreHiddenFolders && (attribs & FileAttributes.Hidden) == FileAttributes.Hidden; ignoreSubDirectory = ignoreSubDirectory || this.Data.KeepSystemFolders && (attribs & FileAttributes.System) == FileAttributes.System; if (!ignoreSubDirectory && this.checkIfDirectoryIsOnIgnoreList(curDir)) { this.Data.AddLogMessage("Aborted scan of \"" + curDir.FullName + "\" because it is on the ignore list."); this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(curDir.FullName, DirectorySearchStatusTypes.Ignore)); ignoreSubDirectory = true; } if (!ignoreSubDirectory && (attribs & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint) { this.Data.AddLogMessage("Aborted scan of \"" + curDir.FullName + "\" because it is a symbolic link"); this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(curDir.FullName, DirectorySearchStatusTypes.Error, "Aborted because dir is a symbolic link")); ignoreSubDirectory = true; } // TODO: Implement more checks //else if ((attribs & FileAttributes.Device) == FileAttributes.Device) msg = "Device - Aborted - found"; //else if ((attribs & FileAttributes.Encrypted) == FileAttributes.Encrypted) msg = "Encrypted - found"; // The file will not be indexed by the operating system's content indexing service. // else if ((attribs & FileAttributes.NotContentIndexed) == FileAttributes.NotContentIndexed) msg = "NotContentIndexed - Device found"; //else if ((attribs & FileAttributes.Offline) == FileAttributes.Offline) msg = "Offline - found"; //else if ((attribs & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) msg = "ReadOnly - found"; //else if ((attribs & FileAttributes.Temporary) == FileAttributes.Temporary) msg = "Temporary - found"; // Scan sub folder: var subFolderStatus = DirectorySearchStatusTypes.NotEmpty; if (!ignoreSubDirectory) { // JRS ADDED check for AGE of folder if (curDir.CreationTime.AddHours(this.Data.MinFolderAgeHours) < DateTime.Now) { subFolderStatus = this.CheckIfDirectoryEmpty(curDir, depth + 1); } else { this.Data.AddLogMessage(String.Format(Resources.young_folder_skipped, curDir.FullName, this.Data.MinFolderAgeHours.ToString(), curDir.CreationTime.ToString())); } // Report status to the GUI if (subFolderStatus == DirectorySearchStatusTypes.Empty) { this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(curDir.FullName, subFolderStatus)); } } // this folder is not empty: if (subFolderStatus != DirectorySearchStatusTypes.Empty || ignoreSubDirectory) { allSubDirectoriesEmpty = false; } } // All subdirectories are empty return(allSubDirectoriesEmpty && !containsFiles ? DirectorySearchStatusTypes.Empty : DirectorySearchStatusTypes.NotEmpty); } catch (Exception ex) { // Error handling if (ex is PathTooLongException) { this.PossibleEndlessLoop++; } this.Data.AddLogMessage("An unknown error occurred while trying to scan this directory: \"" + startDir.FullName + "\" - Error message: " + ex.Message); this.ReportProgress(0, new FoundEmptyDirInfoEventArgs(startDir.FullName, DirectorySearchStatusTypes.Error, ex.Message)); return(DirectorySearchStatusTypes.Error); } }
/// <summary> /// 服务器文件列表与本地对比,逻辑如下: /// 1.如果服务器存在,本地不存在: /// 1.1) 如果文件状态为Deleted,跳过 /// 1.2) 否则,下载 /// 2.如果本地存在,服务器不存在,则上传 /// 3.如果都存在,比较更新时间: /// 3.1) 如果本地较新,则上传,并置文件状态为Modified /// 3.2) 如果服务器较新: /// 3.2.1) 如果文件状态为Deleted,则删除本地文件 /// 3.2.2) 否则,下载文件 /// </summary> /// <param name="path"></param> /// <param name="parentFolder"></param> private void BrowseAndUpdateTree(String path, String parentFolder) { try { var dirInfo = new DirectoryInfo(path); var localFileList = dirInfo.GetFiles(); foreach (var file in localFileList) { var localFile = new FileNode { Id = Guid.NewGuid().ToStringEx(), RelativePath = parentFolder, Name = file.Name, Length = file.Length, UpdateTime = file.LastWriteTimeUtc.Ticks, Status = FileStatus.Added }; var serverFile = serverTree.FileList.FirstOrDefault(item => item.Name.Equals(file.Name)); if (serverFile == null) //condition 2 { logger.Debug("Added upload, {0}.", localFile.Name); uploadFileList.Add(localFile); serverTree.FileList.Add(localFile); } else //condition 3 { if (serverFile.UpdateTime > localFile.UpdateTime) //condition 3.2 { if (serverFile.Status == FileStatus.Deleted) //condition 3.2.1 { logger.Debug("Deleted, {0}.", localFile.Name); File.Delete(file.FullName); } else //condition 3.2.2 { logger.Debug("Added download, {0}.", localFile.Name); downloadFileList.Add(serverFile); } } else //condition 3.1 { logger.Debug("Add upload, {0}.", localFile.Name); serverFile.UpdateTime = localFile.UpdateTime; serverFile.Status = FileStatus.Modified; uploadFileList.Add(localFile); } } } foreach (var serverFile in serverTree.FileList) { var localFile = localFileList.FirstOrDefault(item => item.Name.Equals(serverFile.Name)); if (localFile == null && serverFile.Status != FileStatus.Deleted) //condition 1.2 { logger.Debug("Added download, {0}.", serverFile.Name); downloadFileList.Add(serverFile); } } dirInfo.GetDirectories().ForEach(item => BrowseAndUpdateTree(item.DirectoryName, parentFolder + "\\" + item.Name)); } catch (Exception e) { logger.Debug("Error occurred when browsing folder, info: {0}.", e); } }