public static Task <bool> Start( string FullSrc, string FullTrg, IEnumerable <CopyItem> files, Action <string, UInt64?> OnCopy, Action OnDirectoryCreated, Spi.Native.Win32ApiErrorCallback OnWin32Error, int MaxThreads, bool dryRun) { Console.Error.WriteLine($"I: starting Parallel.ForEach() with MaxDegreeOfParallelism of {MaxThreads}"); return (Task.Run(() => { bool hasErrors = false; try { var result = Parallel.ForEach( source: files, parallelOptions: new ParallelOptions() { MaxDegreeOfParallelism = MaxThreads }, body: (itemToCopy) => { if (!CopyFile.Run( itemToCopy.relativeFilename , itemToCopy.filesize , FullSrc , FullTrg , OnCopy , OnDirectoryCreated , OnWin32Error , dryRun)) { hasErrors = true; } }); } catch (Exception ex) { Console.Error.WriteLine($"Parallel.ForEach()\n{ex}"); } return hasErrors; })); }
public static bool DoCopyFile(string FullSrc, string FullTrg, Spi.Native.Win32ApiErrorCallback OnWin32Error, Action OnCreateDirectory) { if (Spi.Native.CopyFile(lpExistingFileName: FullSrc, lpNewFileName: FullTrg, bFailIfExists: false)) { return(true); } bool ok = false; int LastError = Marshal.GetLastWin32Error(); if (LastError == (int)Spi.Native.Win32Error.ERROR_PATH_NOT_FOUND) { //string FullTargetDirectoryname = System.IO.Path.GetDirectoryName(FullTrg); string FullTargetDirectoryname = Spi.Misc.GetDirectoryName(FullTrg); if (!Spi.Misc.CreatePath(FullTargetDirectoryname, OnWin32Error, OnCreateDirectory)) { OnWin32Error?.Invoke(Marshal.GetLastWin32Error(), "CreateDirectoryW", FullTargetDirectoryname); return(false); } } else if (LastError == (int)Spi.Native.Win32Error.ERROR_ACCESS_DENIED) { if (!Spi.Native.SetFileAttributes(FullTrg, Spi.FileAttributes.Normal)) { OnWin32Error?.Invoke(Marshal.GetLastWin32Error(), "SetFileAttributesW", FullTrg); return(false); } } if (Spi.Native.CopyFile(lpExistingFileName: FullSrc, lpNewFileName: FullTrg, bFailIfExists: false)) { ok = true; } if (!ok) { OnWin32Error?.Invoke(Marshal.GetLastWin32Error(), "CopyFileW", $"\"{FullSrc}\" \"{FullTrg}\""); } return(ok); }
public static bool Run(string relativeFilename, UInt64?filesize, string srcDir, string trgDir, Action <string, UInt64?> OnCopy, Action OnCreateDirectory, Spi.Native.Win32ApiErrorCallback OnWin32Error, bool dryrun) { string FullSrc = Path.Combine(srcDir, relativeFilename); string FullTrg = Path.Combine(trgDir, relativeFilename); if (dryrun) { Console.Out.WriteLine($"\"{FullSrc}\" \"{FullTrg}\""); return(true); } bool ok = DoCopyFile(FullSrc, FullTrg, OnWin32Error, OnCreateDirectory); if (ok) { OnCopy?.Invoke(relativeFilename, filesize); } return(ok); }