예제 #1
0
 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;
 }