/// <summary> /// Copy or move file from source to destination with progress callback /// </summary> /// <param name="source">source file</param> /// <param name="destination">destination file</param> /// <param name="overwrite">true if destination must be overwritten if exists</param> /// <param name="move">true if move, false=copy</param> /// <param name="callback">progress callback method to be called</param> public static void CopyOrMoveFile(string source, string destination, bool overwrite, bool move, CopyFileCallback callback) { if (source == null) { throw new ArgumentNullException("source"); } if (destination == null) { throw new ArgumentNullException("destination"); } new FileIOPermission(FileIOPermissionAccess.Read, source).Demand(); new FileIOPermission(FileIOPermissionAccess.Write, destination).Demand(); CopyProgressData progData = null; NativeMethods.CopyProgressRoutine cpr = null; if (callback != null) { progData = new CopyProgressData(source, destination, callback); cpr = progData.CallbackHandler; } bool cancel = false; if (Environment.OSVersion.Platform == PlatformID.Win32NT) { try { bool ret = true; if (move) { NativeMethods.MoveFileExFlags fm = NativeMethods.MoveFileExFlags.MOVEFILE_COPY_ALLOWED; if (overwrite) { fm |= NativeMethods.MoveFileExFlags.MOVEFILE_REPLACE_EXISTING; } ret = NativeMethods.MoveFileWithProgress(source, destination, cpr, IntPtr.Zero, (int)fm); } else { NativeMethods.CopyFileExFlags f = NativeMethods.CopyFileExFlags.COPY_FILE_ALLOW_DECRYPTED_DESTINATION; if (!overwrite) { f |= NativeMethods.CopyFileExFlags.COPY_FILE_FAIL_IF_EXISTS; } ret = NativeMethods.CopyFileEx(source, destination, cpr, IntPtr.Zero, ref cancel, (int)f); } if (progData != null && progData.Exception != null) { Utils.Rethrow(progData.Exception); } if (!ret) { var w = new Win32Exception(); if (w.NativeErrorCode == 2) { throw new FileNotFoundException(w.Message, source); } throw new IOException(w.Message, w); } return; } catch (MissingMethodException) { } catch (SecurityException) { } } // The old fashioned way if (source != destination) { if (overwrite) { var fi = new FileInfo(destination); if (fi.Exists && (fi.Attributes & (FileAttributes.Hidden | FileAttributes.ReadOnly | FileAttributes.System)) != 0) { fi.Attributes &= ~(FileAttributes.Hidden | FileAttributes.ReadOnly | FileAttributes.System); } fi.Delete(); } if (move) { File.Move(source, destination); } else { File.Copy(source, destination, overwrite); } return; } }
/// <summary> /// Copy or move file from source to destination with progress callback /// </summary> /// <param name="source">source file</param> /// <param name="destination">destination file</param> /// <param name="overwrite">true if destination must be overwritten if exists</param> /// <param name="move">true if move, false=copy</param> /// <param name="callback">progress callback method to be called</param> public static void CopyOrMoveFile(string source, string destination, bool overwrite, bool move, CopyFileCallback callback) { if (source == null) throw new ArgumentNullException("source"); if (destination == null) throw new ArgumentNullException("destination"); new FileIOPermission(FileIOPermissionAccess.Read, source).Demand(); new FileIOPermission(FileIOPermissionAccess.Write, destination).Demand(); CopyProgressData progData = null; NativeMethods.CopyProgressRoutine cpr = null; if (callback != null) { progData = new CopyProgressData(source, destination, callback); cpr = progData.CallbackHandler; } bool cancel = false; if (Environment.OSVersion.Platform == PlatformID.Win32NT) { try { bool ret = true; if (move) { NativeMethods.MoveFileExFlags fm = NativeMethods.MoveFileExFlags.MOVEFILE_COPY_ALLOWED; if (overwrite) fm |= NativeMethods.MoveFileExFlags.MOVEFILE_REPLACE_EXISTING; ret = NativeMethods.MoveFileWithProgress(source, destination, cpr, IntPtr.Zero, (int)fm); } else { NativeMethods.CopyFileExFlags f = NativeMethods.CopyFileExFlags.COPY_FILE_ALLOW_DECRYPTED_DESTINATION; if (!overwrite) f |= NativeMethods.CopyFileExFlags.COPY_FILE_FAIL_IF_EXISTS; ret = NativeMethods.CopyFileEx(source, destination, cpr, IntPtr.Zero, ref cancel, (int)f); } if (progData != null && progData.Exception != null) Utils.Rethrow(progData.Exception); if (!ret) { var w = new Win32Exception(); if (w.NativeErrorCode == 2) throw new FileNotFoundException(w.Message, source); throw new IOException(w.Message, w); } return; } catch (MissingMethodException) { } catch (SecurityException) { } } // The old fashioned way if (source != destination) { if (overwrite) { var fi = new FileInfo(destination); if (fi.Exists && (fi.Attributes & (FileAttributes.Hidden | FileAttributes.ReadOnly | FileAttributes.System))!=0) fi.Attributes&=~(FileAttributes.Hidden | FileAttributes.ReadOnly | FileAttributes.System); fi.Delete(); } if (move) File.Move(source, destination); else File.Copy(source, destination, overwrite); return; } }