コード例 #1
0
        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);
        }
コード例 #2
0
        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);
                }
            }));
        }