private void EraseFilesystemObject(Task task, FileSystemObjectTarget target) { long dataTotal = 0; List<string> paths = target.GetPaths(out dataTotal); ErasureMethod method = target.Method; TaskEventArgs eventArgs = new TaskEventArgs(task); SteppedProgressManager progress = new SteppedProgressManager(); target.Progress = progress; task.Progress.Steps.Add(new SteppedProgressManager.Step(progress, 1.0f / task.Targets.Count)); for (int i = 0; i < paths.Count; ++i) { ProgressManager step = new ProgressManager(); progress.Steps.Add(new SteppedProgressManager.Step(step, 1.0f / paths.Count, S._("Erasing files..."))); task.OnProgressChanged(target, new ProgressChangedEventArgs(step, new TaskProgressChangedEventArgs(paths[i], 0, method.Passes))); StreamInfo info = new StreamInfo(paths[i]); FileSystem fsManager = FileSystemManager.Get( VolumeInfo.FromMountpoint(info.DirectoryName)); if (!info.Exists) { task.Log.LastSessionEntries.Add(new LogEntry(S._("The file {0} was not erased " + "as the file does not exist.", paths[i]), LogLevel.Notice)); continue; } bool isReadOnly = false; try { if (isReadOnly = info.IsReadOnly) info.IsReadOnly = false; if ((info.Attributes & FileAttributes.Compressed) != 0 || (info.Attributes & FileAttributes.Encrypted) != 0 || (info.Attributes & FileAttributes.SparseFile) != 0) { task.Log.LastSessionEntries.Add(new LogEntry(S._("The file {0} could " + "not be erased because the file was either compressed, encrypted or " + "a sparse file.", info.FullName), LogLevel.Error)); } fsManager.EraseFileSystemObject(info, method, delegate(long lastWritten, long totalData, int currentPass) { if (currentTask.Canceled) throw new OperationCanceledException(S._("The task was cancelled.")); step.Completed += lastWritten; step.Total = totalData; task.OnProgressChanged(target, new ProgressChangedEventArgs(step, new TaskProgressChangedEventArgs(info.FullName, currentPass, method.Passes))); }); FileInfo fileInfo = info.File; if (fileInfo != null) fsManager.DeleteFile(fileInfo); step.Completed = step.Total = 1; } catch (UnauthorizedAccessException) { task.Log.LastSessionEntries.Add(new LogEntry(S._("The file {0} could not " + "be erased because the file's permissions prevent access to the file.", info.FullName), LogLevel.Error)); } catch (FileLoadException) { if (!ManagerLibrary.Settings.ForceUnlockLockedFiles) throw; List<System.Diagnostics.Process> processes = new List<System.Diagnostics.Process>(); foreach (OpenHandle handle in OpenHandle.Items) if (handle.Path == paths[i]) processes.Add(System.Diagnostics.Process.GetProcessById(handle.ProcessId)); StringBuilder processStr = new StringBuilder(); foreach (System.Diagnostics.Process process in processes) processStr.AppendFormat(System.Globalization.CultureInfo.InvariantCulture, "{0}, ", process.MainModule.FileName); task.Log.LastSessionEntries.Add(new LogEntry(S._( "Could not force closure of file \"{0}\" (locked by {1})", paths[i], processStr.ToString().Remove(processStr.Length - 2)), LogLevel.Error)); } finally { if (isReadOnly && info.Exists && !info.IsReadOnly) info.IsReadOnly = isReadOnly; } } if (target is FolderTarget) { ProgressManager step = new ProgressManager(); progress.Steps.Add(new SteppedProgressManager.Step(step, 0.0f, S._("Removing folders..."))); FolderTarget fldr = (FolderTarget)target; FileSystem fsManager = FileSystemManager.Get(VolumeInfo.FromMountpoint(fldr.Path)); Action<DirectoryInfo> eraseEmptySubFolders = null; eraseEmptySubFolders = delegate(DirectoryInfo info) { foreach (DirectoryInfo subDir in info.GetDirectories()) eraseEmptySubFolders(subDir); task.OnProgressChanged(target, new ProgressChangedEventArgs(step, new TaskProgressChangedEventArgs(info.FullName, 0, 0))); FileSystemInfo[] files = info.GetFileSystemInfos(); if (files.Length == 0) fsManager.DeleteFolder(info); }; eraseEmptySubFolders(new DirectoryInfo(fldr.Path)); if (fldr.DeleteIfEmpty) { DirectoryInfo info = new DirectoryInfo(fldr.Path); task.OnProgressChanged(target, new ProgressChangedEventArgs(step, new TaskProgressChangedEventArgs(info.FullName, 0, 0))); bool isVolumeRoot = info.Parent == null; foreach (VolumeInfo volume in VolumeInfo.Volumes) foreach (string mountPoint in volume.MountPoints) if (info.FullName == mountPoint) isVolumeRoot = true; if (!isVolumeRoot && info.Exists && info.GetFiles("*", SearchOption.AllDirectories).Length == 0) fsManager.DeleteFolder(info); } } if (target is RecycleBinTarget) { ProgressManager step = new ProgressManager(); progress.Steps.Add(new SteppedProgressManager.Step(step, 0.0f, S._("Emptying recycle bin..."))); task.OnProgressChanged(target, new ProgressChangedEventArgs(step, new TaskProgressChangedEventArgs(string.Empty, 0, 0))); ShellApi.EmptyRecycleBin(EmptyRecycleBinOptions.NoConfirmation | EmptyRecycleBinOptions.NoProgressUI | EmptyRecycleBinOptions.NoSound); } target.Progress = null; }