Пример #1
0
        /// <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;
            }
        }
Пример #2
0
        /// <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;
            }
        }