public static List <LogInfo> DirCopy(EngineState s, CodeCommand cmd) { List <LogInfo> logs = new List <LogInfo>(); CodeInfo_DirCopy info = cmd.Info.Cast <CodeInfo_DirCopy>(); string srcDir = StringEscaper.Preprocess(s, info.SrcDir); string destDir = StringEscaper.Preprocess(s, info.DestDir); Debug.Assert(srcDir != null, $"{nameof(srcDir)} != null"); Debug.Assert(destDir != null, $"{nameof(destDir)} != null"); // Path Security Check if (!StringEscaper.PathSecurityCheck(destDir, out string errorMsg)) { return(LogInfo.LogErrorMessage(logs, errorMsg)); } // DestPath must be directory if (File.Exists(destDir)) { return(LogInfo.LogErrorMessage(logs, $"Cannot overwrite file [{destDir}] with directory [{srcDir}]")); } // Prepare progress report int progressCount = 0; object progressLock = new object(); IProgress <string> progress = new Progress <string>(f => { lock (progressLock) { progressCount += 1; double percent; if (NumberHelper.DoubleEquals(s.MainViewModel.BuildCommandProgressMax, 0)) { percent = 0; } else { percent = progressCount / s.MainViewModel.BuildCommandProgressMax * 100; } s.MainViewModel.BuildCommandProgressText = $"{f}\r\n({percent:0.0}%)"; s.MainViewModel.BuildCommandProgressValue = progressCount; } }); // Check if srcDir contains wildcard string wildcard = Path.GetFileName(srcDir); if (!StringHelper.IsWildcard(wildcard)) { // No Wildcard string destFullPath = Path.Combine(destDir, Path.GetFileName(srcDir)); if (Directory.Exists(destFullPath)) { logs.Add(new LogInfo(LogState.Overwrite, $"Directory [{destFullPath}] will be overwritten with [{srcDir}]")); } else { Directory.CreateDirectory(destFullPath); } // Get total file count int filesCount = FileHelper.GetFilesEx(srcDir, "*", SearchOption.AllDirectories).Length; // Copy directory s.MainViewModel.SetBuildCommandProgress("DirCopy Progress", filesCount); try { FileHelper.DirCopy(srcDir, destFullPath, new DirCopyOptions { CopySubDirs = true, Overwrite = true, Progress = progress, }); logs.Add(new LogInfo(LogState.Success, $"Directory [{srcDir}] copied to [{destFullPath}]", cmd)); } finally { s.MainViewModel.ResetBuildCommandProgress(); } } else { // With Wildcard if (Directory.Exists(destDir)) { logs.Add(new LogInfo(LogState.Overwrite, $"Directory [{destDir}] will be overwritten with [{srcDir}]")); } else { Directory.CreateDirectory(destDir); } string srcParentDir = Path.GetDirectoryName(srcDir); if (srcParentDir == null) { throw new InternalException("Internal Logic Error at DirCopy"); } DirectoryInfo dirInfo = new DirectoryInfo(srcParentDir); if (!dirInfo.Exists) { throw new DirectoryNotFoundException($"Source directory does not exist or cannot be found: {srcDir}"); } // Get total file count int filesCount = 0; FileInfo[] compatFiles = null; if (s.CompatDirCopyBug) { compatFiles = dirInfo.GetFiles(wildcard); filesCount += compatFiles.Length; } DirectoryInfo[] subDirs = dirInfo.GetDirectories(wildcard); foreach (DirectoryInfo d in subDirs) { string[] files = FileHelper.GetFilesEx(d.FullName, "*", SearchOption.AllDirectories); filesCount += files.Length; } // Copy directory s.MainViewModel.SetBuildCommandProgress("DirCopy Progress", filesCount); try { if (s.CompatDirCopyBug) { // Simulate WB082's [DirCopy,%SrcDir%\*,%DestDir%] FileCopy _bug_ Debug.Assert(compatFiles != null, $"Wrong {nameof(compatFiles)}"); foreach (FileInfo f in compatFiles) { progress.Report(f.FullName); File.Copy(f.FullName, Path.Combine(destDir, f.Name), true); } } // Copy first sub-level directory with wildcard // Note wildcard will not be applied to sub-directory copy foreach (DirectoryInfo d in subDirs) { FileHelper.DirCopy(d.FullName, Path.Combine(destDir, d.Name), new DirCopyOptions { CopySubDirs = true, Overwrite = true, Progress = progress, }); } } finally { s.MainViewModel.ResetBuildCommandProgress(); } logs.Add(new LogInfo(LogState.Success, $"Directory [{srcDir}] copied to [{destDir}]", cmd)); } return(logs); }
public static List <LogInfo> DirCopy(EngineState s, CodeCommand cmd) { List <LogInfo> logs = new List <LogInfo>(); Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_DirCopy)); CodeInfo_DirCopy info = cmd.Info as CodeInfo_DirCopy; string srcDir = StringEscaper.Preprocess(s, info.SrcDir); string destDir = StringEscaper.Preprocess(s, info.DestDir); // Path Security Check if (StringEscaper.PathSecurityCheck(destDir, out string errorMsg) == false) { logs.Add(new LogInfo(LogState.Error, errorMsg)); return(logs); } // DestPath must be directory if (File.Exists(destDir)) { logs.Add(new LogInfo(LogState.Error, $"Cannot overwrite file [{destDir}] with directory [{srcDir}]")); return(logs); } // Check srcDir contains wildcard string wildcard = Path.GetFileName(srcDir); if (wildcard.IndexOfAny(new char[] { '*', '?' }) == -1) { // No Wildcard string destFullPath = Path.Combine(destDir, Path.GetFileName(srcDir)); if (Directory.Exists(destFullPath)) { logs.Add(new LogInfo(LogState.Ignore, $"Directory [{destFullPath}] will be overwritten with [{srcDir}]")); } else { Directory.CreateDirectory(destFullPath); } FileHelper.DirectoryCopy(srcDir, destFullPath, true, true, null); logs.Add(new LogInfo(LogState.Success, $"Directory [{srcDir}] copied to [{destFullPath}]", cmd)); } else { // With Wildcard if (Directory.Exists(destDir)) { logs.Add(new LogInfo(LogState.Ignore, $"Directory [{destDir}] will be overwritten with [{srcDir}]")); } else { Directory.CreateDirectory(destDir); } string srcParentDir = Path.GetDirectoryName(srcDir); DirectoryInfo dirInfo = new DirectoryInfo(srcParentDir); if (!dirInfo.Exists) { throw new DirectoryNotFoundException($"Source directory does not exist or cannot be found: {srcDir}"); } if (s.CompatDirCopyBug) { // Simulate WB082's [DirCopy,%SrcDir%\*,%DestDir%] filecopy bug foreach (FileInfo f in dirInfo.GetFiles(wildcard)) { File.Copy(f.FullName, Path.Combine(destDir, f.Name), true); } } // Copy first sublevel directory with wildcard // Note that wildcard will not be applied to subdirectory copy foreach (DirectoryInfo subDir in dirInfo.GetDirectories(wildcard)) { FileHelper.DirectoryCopy(subDir.FullName, Path.Combine(destDir, subDir.Name), true, true, null); } logs.Add(new LogInfo(LogState.Success, $"Directory [{srcDir}] copied to [{destDir}]", cmd)); } return(logs); }