Exemplo n.º 1
0
        /// <summary>
        /// Move <paramref name="sourcePath"/> to <paramref name="destinationPath"/>. If src
        /// and dest are on different partitions (e.g., temp and documents are on different
        /// drives) then this method will do a copy followed by a delete. This is in contrast
        /// to Directory.Move which fails if src and dest are on different partitions.
        /// </summary>
        /// <param name="sourcePath">The source directory or file, similar to Directory.Move</param>
        /// <param name="destinationPath">The destination directory or file. If <paramref name="sourcePath"/>
        /// is a file then <paramref name="destinationPath"/> also needs to be a file.</param>
        public static void Move(string sourcePath, string destinationPath)
        {
            if (PathHelper.AreOnSameVolume(destinationPath, sourcePath))
            {
                Directory.Move(sourcePath, destinationPath);
                return;
            }
            if (Directory.Exists(sourcePath))
            {
                Copy(sourcePath, destinationPath);
                Directory.Delete(sourcePath, true);
            }
            else if (File.Exists(sourcePath))
            {
                if (File.Exists(destinationPath) || Directory.Exists(destinationPath))
                {
                    throw new IOException("Cannot create a file when that file already exists.");
                }

                File.Copy(sourcePath, destinationPath);
                File.Delete(sourcePath);
            }
            else
            {
                throw new DirectoryNotFoundException(
                          string.Format("Could not find a part of the path '{0}'", sourcePath));
            }
        }
Exemplo n.º 2
0
 public static bool PathsAreOnSameVolume(string firstPath, string secondPath)
 {
     return(PathHelper.AreOnSameVolume(firstPath, secondPath));
 }
Exemplo n.º 3
0
        /// <summary>
        /// If there is a problem doing the replace, a dialog is shown which tells the user
        /// what happened, and lets them try to fix it.  It also lets them "Give up", in
        /// which case this returns False.
        ///
        /// To help with situations where something may temporarily be holding on to the file,
        /// this will retry for up to 5 seconds.
        /// </summary>
        /// <param name="sourcePath"></param>
        /// <param name="destinationPath"></param>
        /// <param name="backupPath">can be null if you don't want a replacement</param>
        /// <returns>if the user gives up, throws whatever exception the file system gave</returns>
        public static void ReplaceFileWithUserInteractionIfNeeded(string sourcePath,
                                                                  string destinationPath,
                                                                  string backupPath)
        {
            bool succeeded = false;

            do
            {
                try
                {
                    if (UnsafeForFileReplaceMethod(sourcePath) || UnsafeForFileReplaceMethod(destinationPath)
                        ||
                        (!string.IsNullOrEmpty(backupPath) && !PathHelper.AreOnSameVolume(sourcePath, backupPath))
                        ||
                        !PathHelper.AreOnSameVolume(sourcePath, destinationPath)
                        ||
                        !File.Exists(destinationPath)
                        )
                    {
                        //can't use File.Replace or File.Move across volumes (sigh)
                        RobustFile.ReplaceByCopyDelete(sourcePath, destinationPath, backupPath);
                    }
                    else
                    {
                        var       giveUpTime = DateTime.Now.AddSeconds(5);
                        Exception theProblem;
                        do
                        {
                            theProblem = null;
                            try
                            {
                                File.Replace(sourcePath, destinationPath, backupPath);
                            }
                            catch (UnauthorizedAccessException uae)
                            {
                                // We were getting this while trying to Replace on a JAARS network drive.
                                // The network drive is U:\ which maps to \\waxhaw\users\{username},
                                // so it doesn't get caught by the checks above.
                                // Both files were in the same directory and there were no permissions issues,
                                // but the Replace command was failing with "Access to the path is denied." anyway.
                                // I never could figure out why. See http://issues.bloomlibrary.org/youtrack/issue/BL-4179
                                try
                                {
                                    RobustFile.ReplaceByCopyDelete(sourcePath, destinationPath, backupPath);
                                }
                                catch
                                {
                                    // Though it probably doesn't matter, report the original exception since we prefer Replace to CopyDelete.
                                    theProblem = uae;
                                    Thread.Sleep(100);
                                }
                            }
                            catch (Exception e)
                            {
                                theProblem = e;
                                Thread.Sleep(100);
                            }
                        } while (theProblem != null && DateTime.Now < giveUpTime);
                        if (theProblem != null)
                        {
                            throw theProblem;
                        }
                    }
                    succeeded = true;
                }
                catch (UnauthorizedAccessException error)
                {
                    ReportFailedReplacement(destinationPath, error);
                }
                catch (IOException error)
                {
                    ReportFailedReplacement(destinationPath, error);
                }
            }while (!succeeded);
        }