/// <summary> /// Parses the passed command line arguments, handles if a batch job was specified, /// runs the deletion operation. Main entry point for the class. /// </summary> /// <param name="path">0th argument passed in (file or folder to delete)</param> /// <param name="cla">The structured command line arguments</param> public static void Run(string path, CommandLineArgs cla) { _ca = new CompletionAction(); // First, parse the command line arguments and assign them to varibles ParseArgs(cla); // If we aren't running a batch job... if (!_batch) { Target target = new Target(path); // If the target exists if (target.Exists) { // Try deleting the target try { DeletionOps.MultithreadingSetup mt = new DeletionOps.MultithreadingSetup(_multithreading, _numThreads); DeletionOps.Logging log = new DeletionOps.Logging(_logging, _logTo); _error = DeletionOps.Delete(target, mt, log, !_quiet); } catch (Exception ex) { // If the user specifies quiet mode, don't display exception if (!_quiet) Console.WriteLine(ex.ToString()); _error = 1; } finally { // If it was a success if (_error == 0) { CleanupDirectory(target); // No command is specified, run the completion action if (string.IsNullOrEmpty(_command)) _ca.Run(false, _forceAction); // Otherwise, run the custom command else if (!string.IsNullOrEmpty(_command)) RunCommand(); } } } // If the target doesn't exist and we're not in quiet mode, write the error else if (!target.Exists && !_quiet) Console.WriteLine(SharedResources.Properties.Resources.TargetNotFound); } else { // If the user passed a job file and it exists, execute it if (File.Exists(_jobFile)) RunJobDeletion(); // Otherwise display an error else if (!_quiet) Console.WriteLine(SharedResources.Properties.Resources.JobFileNotFound); } }
/// <summary> /// Handles the deletion of the passed target /// </summary> /// <param name="target">The file or directory to be deleted</param> /// <param name="mt">Multithreading configuration</param> /// <param name="log">Logging configuration</param> /// <param name="output">Output enabled</param> /// <returns>An error code based on how the operation turned out</returns> public static int Delete(Target target, MultithreadingSetup mt, Logging log, bool output) { int retval = (int) ErrorCodes.Success; if (target.Exists) { // Create empty directory for mirroring string emptyDir = SystemTempDir + @"\FilExile_temp$"; string secondEmptyDir = ""; Directory.CreateDirectory(emptyDir); // Sometimes there's an extra backslash on the end of the path // and we need to trim it off if (target.Path.EndsWith(@"\")) target.Path = target.Path.TrimEnd('\\'); if (target.IsDirectory) { _robocopyCommand = PrepareRobocopyCommand(mt, log, emptyDir, target.Path); } else { // For single files there is an extra step we have to take... // We need to create another temporary directory. We are going to use Robocopy // to place the file in this temporary directory by itself. This is to // prevent the actual diretory mirror command from wiping out everything else // where the file was found. secondEmptyDir = SystemTempDir + @"\FilExile_singleFile_temp$"; Directory.CreateDirectory(secondEmptyDir); string fileCopyCmd = PrepareFileCopyCommand(target.ParentDirectory, secondEmptyDir, target.FileName); RunRobocopy(fileCopyCmd, output); _robocopyCommand = PrepareRobocopyCommand(mt, log, emptyDir, secondEmptyDir); } // This is where the main deletion operation occurs - Uses Robocopy to mirror // the empty directory we created onto the target. This will make any files within // the target appear as "extra files" and forcibly remove them via Robocopy which // can handle all sorts of nasty files that Windows will sometimes choke on RunRobocopy(_robocopyCommand, output); // Delete the temporary directory/directories created if (Directory.Exists(emptyDir)) { Directory.Delete(emptyDir); } if (Directory.Exists(secondEmptyDir)) { Directory.Delete(secondEmptyDir); } } else { retval = (int) ErrorCodes.NotFound; } return retval; }
/// <summary> /// Creates a StreamReader to parse the job file. Reads in each line as a separate file or directory /// to delete. /// </summary> private static void RunJobDeletion() { StreamReader din = File.OpenText(_jobFile); string str; Target target = new Target(); DeletionOps.MultithreadingSetup mt = new DeletionOps.MultithreadingSetup(_multithreading, _numThreads); DeletionOps.Logging log = new DeletionOps.Logging(_logging, _logTo); // While there are still more lines to read and no errors have been encountered while (!string.IsNullOrEmpty((str = din.ReadLine())) && _error == 0) { // Set the target's path based on the line target.Path = str; // Run the deletion _error = DeletionOps.Delete(target, mt, log, !_quiet); } }
/// <summary> /// Deletes the original target directory (if it's still there) /// </summary> /// <param name="target">The original <see cref="Target"/></param> private static void CleanupDirectory(Target target) { if (target.IsDirectory && target.Exists) { Directory.Delete(target.Path); } }
/// <summary> /// When the user clicks the delete button, disable the controls and start the /// deletion operation /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button_delete_Click(object sender, EventArgs e) { // Disable the controls ChangeControlStates(false); bool cont = true; _target = new Target(field_target.Text); if (_target.Exists) { if (_target.IsCritical) cont = CriticalTargetWarning(); if (cont) { try { // If the user wants to monitor progress and the target is a directory // we need to setup the progress bar if (_target.IsDirectory) { _iNumFiles = _target.NumberOfFiles; progressBar.Maximum = _iNumFiles; progressBar.Visible = true; backgroundWorker_ProgressBar.RunWorkerAsync(); } backgroundWorker_Deletion.RunWorkerAsync(); } catch (UnauthorizedAccessException) { //TODO: Write code to request elevation for a new process? } catch (FileNotFoundException) { //TODO: Write code to handle this strange exception... } catch (DirectoryNotFoundException) { //TODO: Write code to handle this strange exception... } } else { ChangeControlStates(true); } } else { //Target doesn't exist, display an error MessageBox.Show(SharedResources.Properties.Resources.TargetNotFound, SharedResources.Properties.Resources.Error); } }