public static void ReplaceByCopyDelete(string sourcePath, string destinationPath, string backupPath) { RobustFile.ReplaceByCopyDelete(sourcePath, destinationPath, backupPath); }
/// <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); }