private void btnCreate_Click(object sender, EventArgs e) { FolderMoveAction action = new FolderMoveAction(txbSource.Text, txbDestination.Text); if (!Directory.Exists(action.SourcePath)) { MessageBox.Show($"Source folder {action.SourcePath} does not exist.\n\nPlease choose an existing folder.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else if (Directory.Exists(action.DestinationPath) && (Directory.GetFiles(action.DestinationPath).Count() > 0 || Directory.GetDirectories(action.DestinationPath).Count() > 0)) { MessageBox.Show($"Destination folder {action.DestinationPath} is not empty!\n\nPlease choose an empty folder.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } else { var worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true, }; worker.DoWork += Worker_DoWork; worker.RunWorkerCompleted += Worker_RunWorkerCompleted; progressWindow = new frmProgress(worker); progressWindow.Left = Left; progressWindow.Top = Top; progressWindow.Show(); Visible = false; worker.RunWorkerAsync(action); } }
private void Worker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = ((BackgroundWorker)sender); FolderMoveAction action = ((FolderMoveAction)e.Argument); FolderMoveResult result = new FolderMoveResult(); e.Result = result; worker.ReportProgress(0, "calculation folder size"); var folderCount = GetDirectoryCount(action.SourcePath); var fileSizes = GetDirectorySize(action.SourcePath); long progressMax = folderCount + fileSizes; long progress = 0; if (!Directory.Exists(action.DestinationPath)) { worker.ReportProgress(0, $"creating folder {action.DestinationPath}"); Directory.CreateDirectory(action.DestinationPath); result.SetFlag(enumFolderMoveResult.DeleteDestination); } // createing directory tree and copy files var directories = new Stack <string>(); directories.Push(action.SourcePath); result.SetFlag(enumFolderMoveResult.CleanDestination); while (directories.Count > 0 && !worker.CancellationPending) { var basePath = directories.Pop(); foreach (var d in Directory.EnumerateDirectories(basePath)) { var newDirectory = Path.Combine(action.DestinationPath, d.Substring(action.SourcePath.Length + 1)); worker.ReportProgress(CalcProgress(progress, progressMax), $"creating folder {newDirectory}"); Directory.CreateDirectory(newDirectory); directories.Push(d); progress++; if (worker.CancellationPending) { return; } } foreach (var f in Directory.EnumerateFiles(basePath)) { var destPath = Path.Combine(action.DestinationPath, f.Substring(action.SourcePath.Length + 1)); FileInfo info = new FileInfo(f); worker.ReportProgress(CalcProgress(progress, progressMax), $"copying to {destPath}"); File.Copy(f, destPath); progress += info.Length; if (worker.CancellationPending) { return; } } } // moveing old folder if (worker.CancellationPending) { return; } worker.ReportProgress(CalcProgress(progress, progressMax), $"renaming {Path.GetFileName(action.SourcePath)} to {Path.GetFileName(action.SourcePath)}.old .."); string sourceCopy = Path.Combine(Path.GetTempPath(), Path.GetFileName(action.SourcePath) + ".old"); try { Directory.Move(action.SourcePath, sourceCopy); } catch (Exception ex) { MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); result.SetFlag(enumFolderMoveResult.RevertMoveSource); } // create link if (worker.CancellationPending) { return; } worker.ReportProgress(CalcProgress(progress, progressMax), $"creating symbolic link .."); using (Process process = new Process()) { process.StartInfo = new ProcessStartInfo { FileName = "cmd", Arguments = $"/c mklink /J \"{action.SourcePath}\" \"{action.DestinationPath}\"", UseShellExecute = false, CreateNoWindow = true, RedirectStandardError = true, RedirectStandardOutput = true, }; process.ErrorDataReceived += Process_ErrorDataReceived; process.OutputDataReceived += Process_OutputDataReceived; process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit(); if (process.ExitCode != 0) { result.SetFlag(enumFolderMoveResult.DeleteLink); } process.Close(); } // removeing old folder if (worker.CancellationPending) { return; } Directory.Delete(sourceCopy, true); // finishing if (worker.CancellationPending) { return; } result.Reset(); }