public static List <LogInfo> FileCopy(EngineState s, CodeCommand cmd) { List <LogInfo> logs = new List <LogInfo>(); CodeInfo_FileCopy info = cmd.Info.Cast <CodeInfo_FileCopy>(); string srcFile = StringEscaper.Preprocess(s, info.SrcFile); string destPath = StringEscaper.Preprocess(s, info.DestPath); Debug.Assert(srcFile != null, $"{nameof(srcFile)} != null"); Debug.Assert(destPath != null, $"{nameof(destPath)} != null"); // Path Security Check if (!StringEscaper.PathSecurityCheck(destPath, out string errorMsg)) { return(LogInfo.LogErrorMessage(logs, errorMsg)); } // Check srcFileName contains wildcard string wildcard = Path.GetFileName(srcFile); if (!StringHelper.IsWildcard(wildcard)) { // No Wildcard if (Directory.Exists(destPath)) { // DestPath exists, and it is directory Directory.CreateDirectory(destPath); string destFullPath = Path.Combine(destPath, Path.GetFileName(srcFile)); if (File.Exists(destFullPath)) { if (info.Preserve) { logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"[{destFullPath}] will not be overwritten")); return(logs); } logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"File [{destFullPath}] will be overwritten")); } File.Copy(srcFile, destFullPath, true); logs.Add(new LogInfo(LogState.Success, $"[{srcFile}] copied to [{destFullPath}]")); } else if (FileHelper.IsPathNonExistDir(destPath)) { // DestPath ends with \, warn user logs.Add(new LogInfo(LogState.Warning, $"Unable to copy a file, directory [{destPath}] does not exist")); } else { // DestPath does not exist, or it is a file string destDir = FileHelper.GetDirNameEx(destPath); Directory.CreateDirectory(destDir); if (File.Exists(destPath)) { if (info.Preserve) { logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"[{destPath}] will not be overwritten")); return(logs); } logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"File [{destPath}] will be overwritten")); } File.Copy(srcFile, destPath, true); logs.Add(new LogInfo(LogState.Success, $"[{srcFile}] copied to [{destPath}]")); } } else { // With Wildcard // Use FileHelper.GetDirNameEx to prevent ArgumentException of Directory.GetFiles string srcDirToFind = Path.GetFullPath(FileHelper.GetDirNameEx(srcFile)); string[] files = FileHelper.GetFilesEx(srcDirToFind, wildcard, info.NoRec ? SearchOption.TopDirectoryOnly : SearchOption.AllDirectories); if (files.Length == 0) { logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Warning, $"No files were found in [{srcDirToFind}]")); return(logs); } if (!Directory.Exists(destPath) && File.Exists(destPath)) { logs.Add(new LogInfo(LogState.Success, $"Cannot copy [{srcFile}] into [{destPath}]")); logs.Add(new LogInfo(LogState.Error, "The file destination must be directory when using wildcards (? *) in the <SrcFile> name")); return(logs); } // One or more file will be copied logs.Add(new LogInfo(LogState.Success, $"[{srcFile}] will be copied to [{destPath}]")); s.MainViewModel.SetBuildCommandProgress("FileCopy Progress", files.Length); try { for (int i = 0; i < files.Length; i++) { string f = files[i]; string destFullPath = Path.Combine(destPath, FileHelper.SubRootDirPath(f, srcDirToFind)); if (File.Exists(destFullPath)) { if (info.Preserve) { logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"[{destFullPath}] will not be overwritten")); continue; } logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"[{destFullPath}] will be overwritten")); } string destFullParent = Path.GetDirectoryName(destFullPath); if (destFullParent == null) { throw new InternalException("Internal Logic Error at FileCopy"); } s.MainViewModel.BuildCommandProgressText = $"{f}\r\n({(double)(i + 1) / files.Length * 100:0.0}%)"; Directory.CreateDirectory(destFullParent); File.Copy(f, destFullPath, true); s.MainViewModel.BuildCommandProgressValue = i + 1; logs.Add(new LogInfo(LogState.Success, $"[{f}] copied to [{destFullPath}]")); } } finally { s.MainViewModel.ResetBuildCommandProgress(); } logs.Add(new LogInfo(LogState.Success, $"[{files.Length}] files copied")); } return(logs); }
public static List <LogInfo> FileCopy(EngineState s, CodeCommand cmd) { List <LogInfo> logs = new List <LogInfo>(); Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_FileCopy)); CodeInfo_FileCopy info = cmd.Info as CodeInfo_FileCopy; string srcFile = StringEscaper.Preprocess(s, info.SrcFile); string destPath = StringEscaper.Preprocess(s, info.DestPath); // Path Security Check if (StringEscaper.PathSecurityCheck(destPath, out string errorMsg) == false) { logs.Add(new LogInfo(LogState.Error, errorMsg)); return(logs); } // Check destPath is directory bool destPathExists = false; bool destPathIsDir = false; if (Directory.Exists(destPath)) { destPathExists = true; destPathIsDir = true; } else if (File.Exists(destPath)) { destPathExists = true; } // Check srcFileName contains wildcard string wildcard = Path.GetFileName(srcFile); if (wildcard.IndexOfAny(new char[] { '*', '?' }) == -1) { // No Wildcard if (destPathIsDir) // DestPath exists, and it is directory { Directory.CreateDirectory(destPath); string destFullPath = Path.Combine(destPath, Path.GetFileName(srcFile)); if (File.Exists(destFullPath)) { if (info.Preserve) { logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"Cannot overwrite file [{destFullPath}]", cmd)); return(logs); } else { logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"File [{destFullPath}] will be overwritten", cmd)); } } File.Copy(srcFile, destFullPath, true); logs.Add(new LogInfo(LogState.Success, $"[{srcFile}] copied to [{destFullPath}]", cmd)); } else // DestPath not exist, or it is a file { Directory.CreateDirectory(FileHelper.GetDirNameEx(destPath)); if (destPathExists) { if (info.Preserve) { logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"Cannot overwrite file [{destPath}]", cmd)); return(logs); } else { logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"File [{destPath}] will be overwritten", cmd)); } } File.Copy(srcFile, destPath, true); logs.Add(new LogInfo(LogState.Success, $"[{srcFile}] copied to [{destPath}]", cmd)); } } else { // With Wildcard // Use FileHelper.GetDirNameEx to prevent ArgumentException of Directory.GetFiles string srcDirToFind = Path.GetFullPath(FileHelper.GetDirNameEx(srcFile)); string[] files; if (info.NoRec) { files = FileHelper.GetFilesEx(srcDirToFind, wildcard); } else { files = FileHelper.GetFilesEx(srcDirToFind, wildcard, SearchOption.AllDirectories); } if (0 < files.Length) { // One or more file will be copied logs.Add(new LogInfo(LogState.Success, $"[{srcFile}] will be copied to [{destPath}]", cmd)); if (destPathIsDir || !destPathExists) { for (int i = 0; i < files.Length; i++) { string f = files[i]; string destFullPath = Path.Combine(destPath, f.Substring(srcDirToFind.Length + 1)); if (File.Exists(destFullPath)) { if (info.Preserve) { logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"Cannot overwrite [{destFullPath}]", cmd)); continue; } else { logs.Add(new LogInfo(info.NoWarn ? LogState.Ignore : LogState.Overwrite, $"[{destFullPath}] will be overwritten", cmd)); } } Directory.CreateDirectory(Path.GetDirectoryName(destFullPath)); File.Copy(f, destFullPath, true); logs.Add(new LogInfo(LogState.Success, $"[{f}] copied to [{destFullPath}]", cmd)); } logs.Add(new LogInfo(LogState.Success, $"[{files.Length}] files copied", cmd)); } else { logs.Add(new LogInfo(LogState.Error, "<DestPath> must be directory when using wildcard in <SrcFile>", cmd)); return(logs); } } else { // No file will be copied logs.Add(new LogInfo(LogState.Ignore, $"Files matching wildcard [{srcFile}] not found", cmd)); } } return(logs); }