private Task ScanExistingFilesToProcess(CancellationToken ct) { lock (_scanLock) { if (_fileScanTask.IsCanceled || _fileScanTask.IsCompleted || _fileScanTask.IsFaulted) { _fileScanTask = Task.Run( () => { foreach (string filePath in SafeFileEnumerator.EnumerateFiles(this.Settings.SourceFolder, this.Settings.Filter, SearchOption.AllDirectories)) { if (ct.IsCancellationRequested) { break; } FileInfo sourceInfo; try { sourceInfo = new FileInfo(filePath); } catch (IOException) { continue; } foreach (var folder in this.Settings.DestinationFolders) { // do not stop the processing here in case of cancellation // because we must stay coherent when sending events by file // i.e. we must be careful not to send a partial destination list for a file var destInfo = new FileInfo(GetDestinationFilePath(filePath, folder)); if (!IOHelper.AreSameFile(sourceInfo, destInfo)) { var newFileData = new FileTransferData { MachineName = Environment.MachineName, MonitoredFolderPath = _monitor.Path, DestinationFolderPath = folder, FileName = sourceInfo.Name, TotalBytes = sourceInfo.Length }; _fileTransferSubject.OnNext(newFileData); } } } }); } } return(_fileScanTask); }
public static Task Copy(string source, string destination, OverwriteMode overwriteMode, CopyOptions options, CancellationToken?cancellationToken = null, Action <long, long> progressCallback = null) { if (string.IsNullOrEmpty(source)) { throw new ArgumentNullException("source"); } if (string.IsNullOrEmpty(destination)) { throw new ArgumentNullException("destination"); } var copyFileFlags = CopyFileFlags.COPY_FILE_RESTARTABLE; if (overwriteMode != OverwriteMode.AlwaysOverwrite) { copyFileFlags |= CopyFileFlags.COPY_FILE_FAIL_IF_EXISTS; } if (options.HasFlag(CopyOptions.DisableBuffering)) { copyFileFlags |= CopyFileFlags.COPY_FILE_NO_BUFFERING; } int isCancelled = 0; var ct = cancellationToken ?? CancellationToken.None; CopyProgressRoutine progressRoutine = (total, transferred, streamSize, streamByteTrans, dwStreamNumber, reason, hSourceFile, hDestinationFile, lpData) => { if (progressCallback != null && reason == CopyProgressCallbackReason.CALLBACK_CHUNK_FINISHED) { progressCallback(transferred, total); } if (ct.IsCancellationRequested) { return(CopyProgressResult.PROGRESS_CANCEL); } else { return(CopyProgressResult.PROGRESS_CONTINUE); } }; return(Task.Run( () => { if (!CopyFileEx(source, destination, progressRoutine, IntPtr.Zero, ref isCancelled, copyFileFlags)) { int errorCode = Marshal.GetLastWin32Error(); // https://msdn.microsoft.com/en-us/library/cc231199.aspx // ERROR_FILE_EXISTS = 0x00000050; // ERROR_ALREADY_EXISTS = 0x000000B7 // ERROR_OBJECT_ALREADY_EXISTS = 0x00001392 // ERROR_OBJECT_NAME_EXISTS = 0x000002BA if (errorCode == 0x00000050 || errorCode == 0x000000B7 || errorCode == 0x00001392 || errorCode == 0x000002BA) { if (overwriteMode == OverwriteMode.OverwriteIfDifferent) { if (IOHelper.AreSameFile(source, destination)) { return; } else { copyFileFlags &= ~CopyFileFlags.COPY_FILE_FAIL_IF_EXISTS; if (CopyFileEx(source, destination, progressRoutine, IntPtr.Zero, ref isCancelled, copyFileFlags)) { return; } } } } throw new Win32Exception(errorCode); } })); }