private void GetFileInfo(params string[] args) { /* Check and parse path to the file */ var pathArg = args[0]; string path = ExtraFunctional.ParsePath(pathArg, CurrentDirectory); // path can be null only if current directory is null if (path is null) { CurrentShownInfo = new Info( "Невозможно использовать указанный путь. Укажите абсолютный путь.", InfoType.Error ); return; } if (!File.Exists(path) && !Directory.Exists(path)) { CurrentShownInfo = new Info( "Ошибка исполнения команды: указанный файл или директория не существует.", InfoType.Error ); return; } /* Get info */ string info; // main information string name; string extension; string location; // size information long sizeBytes; FileAttributes attributes; try { if (ExtraFunctional.IsDrive(path)) { var driveInfo = new DriveInfo(path); info = CreateDriveInfo(driveInfo); } else if (ExtraFunctional.IsFile(path)) { /* Collect main information */ name = Path.GetFileNameWithoutExtension(path); extension = Path.GetExtension(path); location = Path.GetDirectoryName(path); attributes = File.GetAttributes(path); /* Try to get the size of the file */ try { var dirFilesInfo = new List <FileInfo>(new DirectoryInfo(location).GetFiles()); FileInfo fileInfo = dirFilesInfo.Find(fInfo => fInfo.Name == (name + extension)); sizeBytes = fileInfo.Length; } catch (Exception e) { // exception will be thrown only if app has no rights to access the file or folder // in that case just warn the user about it and show the size of the file as 'Неизвестно' sizeBytes = -1; ShowFileOperationDialog( "Отказано в доступе к файлу", "У приложения отсутствуют необходимые права для получения информации о размерах" + $" файла {name}{extension}. Размер файла будет указан, как \"Неизвестно\".", "продолжить", null, null ); } /* Create info string */ info = CreateFileInfo( name, extension, location, sizeBytes, File.GetCreationTime(path), File.GetLastWriteTime(path), File.GetLastAccessTime(path), attributes ); } else { name = Path.GetFileNameWithoutExtension(path); location = Path.GetDirectoryName(path); /* Try to get the size of the directory and its attributes */ var dirDirsInfo = new List <DirectoryInfo>(new DirectoryInfo(location).GetDirectories()); DirectoryInfo dirInfo = dirDirsInfo.Find(dInfo => dInfo.Name == name); attributes = dirInfo.Attributes; // show info window to let user know that application is not frozen Console.Clear(); CurrentShownInfo = new Info( "Выполняется вычисление размера папки. Пожалуйста, подождите..." ); ShowInfoWindow("Вычисление размера папки"); try { sizeBytes = dirInfo.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length); } catch (Exception e) { // exception will be thrown only if app has no rights to access the file or folder // in that case just warn the user about it and show the size of the file as 'Неизвестно' sizeBytes = -1; ShowFileOperationDialog( "Отказано в доступе к файлу", "У приложения отсутствуют необходимые права для получения информации о размерах" + $" папки {name}. Размер папки будет указан, как \"Неизвестно\".", "продолжить", null, null ); } /* Create info string */ info = CreateDirInfo( name, location, sizeBytes, dirInfo.CreationTime, attributes ); } } catch (Exception e) { ErrorLogger.LogError(e); var type = ExtraFunctional.IsDrive(path) ? "диске" : (ExtraFunctional.IsFile(path) ? "файле" : "папке"); CurrentShownInfo = new Info( $"Произошла ошибка при попытке получить информацию о {type}: {e.Message}", InfoType.Error ); return; } CurrentShownInfo = new Info(info, InfoType.FileInfo); }
private void Delete(params string[] args) { /* Check and parse arguments */ var pathArg = args[0]; var recursiveArg = args[1]; string path; bool recursiveDeletion; path = ExtraFunctional.ParsePath(pathArg, CurrentDirectory); // path can be null only if current directory is null if (path is null) { CurrentShownInfo = new Info( "Невозможно использовать указанный путь. Укажите абсолютный путь.", InfoType.Error ); return; } if (!File.Exists(path) && !Directory.Exists(path)) { CurrentShownInfo = new Info( "Ошибка исполнения команды: указанный файл или директория не существует.", InfoType.Error ); return; } recursiveDeletion = recursiveArg != null; var isFile = Path.HasExtension(path); try { if (isFile) { File.Delete(path); } else { if (Directory.GetFileSystemEntries(path).Length != 0 && recursiveDeletion == false) { CurrentShownInfo = new Info( "Указанная директория не пуста. Если вы желаете удалить папку вместе со всем её " + "содержимым, повторите команду, указав аргумент рекурсивного удаления:\n" + $"del \"{path}\" -r true" ); return; } // show a stub window so that the user knows that the program is not frozen CurrentShownInfo = new Info("Идёт операция удаления файлов. Пожалуйста, подождите..."); ShowInfoWindow("Операция"); // recursively delete all files and dirs var deletedSuccessfully = RecursiveFilesDeletion(path); if (deletedSuccessfully) { Directory.Delete(path); } CurrentShownInfo = deletedSuccessfully ? Info.Empty : new Info("Операция удаления была прервана."); if (CurrentDirectory == path) { CurrentDirectory = Path.GetDirectoryName(path.TrimEnd('\\')); } } } catch (Exception e) { ErrorLogger.LogError(e); CurrentShownInfo = new Info( $"Произошла ошибка при попытке удалить {(isFile ? "файл" : "папку")}: {e.Message}", InfoType.Error ); } }
private void Copy(params string[] args) { /* Check and parse arguments */ var copiedPathArg = args[0]; var destinationPathArg = args[1]; var replaceFileArg = args[2]; string copiedPath; string destinationPath; bool replaceFiles; copiedPath = ExtraFunctional.ParsePath(copiedPathArg, CurrentDirectory); destinationPath = ExtraFunctional.ParsePath(destinationPathArg, CurrentDirectory); // path can be null only if current directory is null if (copiedPath is null) { CurrentShownInfo = new Info( "Невозможно использовать указанный путь. Укажите абсолютный путь.", InfoType.Error ); return; } // check if copied file or directory exists if (!File.Exists(copiedPath) && !Directory.Exists(copiedPath)) { CurrentShownInfo = new Info( "Ошибка исполнения команды: указанный файл или директория не существует.", InfoType.Error ); return; } var copiedObjIsFile = Path.HasExtension(copiedPath); // check if destination path is a directory that exists if (!Directory.Exists(destinationPath)) { CurrentShownInfo = new Info( "Ошибка исполнения команды: папки назначения не существует, либо путь указывал на файл.", InfoType.Error ); return; } // parse extra arg replaceFiles = replaceFileArg is null ? false : bool.Parse(replaceFileArg); try { var newFilePath = Path.Combine(destinationPath, Path.GetFileName(copiedPath)); if (copiedObjIsFile) { // if file in destination folder exists and no extra arg was specified // then warn the user if (replaceFileArg is null && File.Exists(newFilePath)) { CurrentShownInfo = new Info( $"В папке назначения уже есть файл с именем {Path.GetFileName(newFilePath)}.\n" + "Если вы желаете заменить файл в папке назначения, " + "повторите команду с указанием аргумента замены как true:\n" + $"cpy \"{copiedPath}\" \"{destinationPath}\" -rf true\n" + "Если же вы желаете создать в папке назначения ещё один такой же файл, " + "повторите команду с указанием аргумента замены как false:\n" + $"cpy \"{copiedPath}\" \"{destinationPath}\" -rf false" ); return; } // if replace file arg was specified as false, then create new name for the copied file if (!replaceFiles && File.Exists(newFilePath)) { var newFileName = ExtraFunctional.GetCopyFileName( newFilePath, Directory.GetFiles(destinationPath) ); newFilePath = Path.Combine(destinationPath, newFileName); } File.Copy(copiedPath, newFilePath, replaceFiles); CurrentShownInfo = Info.Empty; } else { var newDirPath = Path.Combine(destinationPath, Path.GetFileName(copiedPath)); if (!Directory.Exists(newDirPath)) { Directory.CreateDirectory(newDirPath); } // show a stub window so that the user knows that the program is not frozen CurrentShownInfo = new Info("Идёт операция копирования файлов. Пожалуйста, подождите..."); ShowInfoWindow("Операция"); // recursively copy all files and dirs to another dir var copiedSuccessfully = RecursiveFilesCopy(copiedPath, newDirPath, replaceFiles); CurrentShownInfo = copiedSuccessfully ? Info.Empty : new Info("Операция копирования была прервана."); } } catch (Exception e) { ErrorLogger.LogError(e); CurrentShownInfo = new Info( $"Произошла ошибка при попытке скопировать {(copiedObjIsFile ? "файл" : "папку")}: {e.Message}", InfoType.Error ); } }
/// <summary> /// Show files from the current directory on the current page. /// </summary> public void ShowFilesWindow() { // current directory can be null only if there was a serious problem with all drives caused by OS (could not get // root directory on any drive), so the only left option is to show error message and empty window. if (CurrentDirectory is null) { ShowFiles(new List <string>(), 1, config.FilesPerPage); return; } var dirsAndFilesList = new List <string>(); try { /* Get all files and directories from the current directory*/ var dirsAndFiles = Directory.GetFileSystemEntries(CurrentDirectory); foreach (var df in dirsAndFiles) { var nameWithoutPath = Path.GetFileName(df); // if extension is empty then it is directory [D], otherwise it is file [F] var type = Path.GetExtension(df) == string.Empty ? "[D]" : "[F]"; // in the console it should be shown as: '[D] SomeDirectory' or: '[F] SomeFile.ext' dirsAndFilesList.Add($"{type} {nameWithoutPath}"); } } catch (Exception e) { // the execution can get here only if there is a serious problem with directory that is caused by OS, // so application can not handle it, and it's better to show an error message to user to let them know it, // then just show the drive's root. ErrorLogger.LogError(e); // show message saying that there is a problem with current directory that can not be handled by the application CurrentShownInfo = new Info( "Произошла проблема с текущей директорией. Попробуйте перейти в другую директорию.", InfoType.Error ); // show empty window ShowFiles(new List <string>(), 1, config.FilesPerPage); return; } /* Check if page number is correct */ // from there both directories and files will be called files (in variables names) var totalFilesAmount = dirsAndFilesList.Count; // number of the first shown file on the current page var firstShownFileNum = (CurrentShownPage - 1) * config.FilesPerPage; // number of the last shown file on the current page var lastShownFileNum = CurrentShownPage * config.FilesPerPage - 1; if (totalFilesAmount - 1 < firstShownFileNum) { if (totalFilesAmount == 0) { CurrentShownInfo = new Info( "Директория пуста.", InfoType.Warning ); } else { CurrentShownInfo = new Info( "На странице с указанными номером нет файлов. Показана первая страница.", InfoType.Warning ); CurrentShownPage = 1; firstShownFileNum = 0; lastShownFileNum = config.FilesPerPage - 1; } } /*Draw window and show files */ ShowFiles(dirsAndFilesList, firstShownFileNum, lastShownFileNum); }
/// <summary> /// Restore current directory and shown page since the last app work. <para/> /// Current directory and shown page are read from the save file. If save file does not contain saved directory /// then directory will be taken as root of any available drive. /// </summary> public void RestoreLastState() { string restoredDirectory; string restoredPage; try { using var fs = new FileStream(Settings.Default.lastStateSaveFilePath, FileMode.Open, FileAccess.Read); using var sr = new StreamReader(fs); restoredDirectory = sr.ReadLine(); restoredPage = sr.ReadLine(); // if restored directory is null or empty then saved data was manually deleted by the user // or it's the first application start and nothing was saved yet. if (string.IsNullOrEmpty(restoredDirectory)) { // apply root directory of the drive as current and set the first page as page to show var restoredFromDrive = TryRestoreFromRootOnAnyDrive(out restoredDirectory, out restoredPage); if (!restoredFromDrive) { return; } } else if (string.IsNullOrEmpty(restoredPage)) { // set the first page as page to show restoredPage = Settings.Default.showPageDefault.ToString(); } } catch (Exception e) { ErrorLogger.LogError(e); // apply root directory of the drive as current and set the first page as page to show var restoredFromDrive = TryRestoreFromRootOnAnyDrive(out restoredDirectory, out restoredPage); if (!restoredFromDrive) { return; } } // it restored directory does not exist then try to get a root path on any drive if (!Directory.Exists(restoredDirectory)) { // apply root directory of the drive as current and set the first page as page to show var restoredFromDrive = TryRestoreFromRootOnAnyDrive(out restoredDirectory, out restoredPage); if (!restoredFromDrive) { return; } } // if restored path exists and correct then take it as current directory CurrentDirectory = restoredDirectory; // check if restored page number is an integer number // if not - then take the default value CurrentShownPage = int.TryParse(restoredPage, out var page) ? page : Settings.Default.showPageDefault; // if last state restored successfully then there is no info to show CurrentShownInfo = Info.Empty; }
/// <summary> /// Get the root directory on the first available fixed of removable drive. <para/> /// If there is no any, then get the root directory of the first available drive. <para/> /// If there is problems with all checked drives, then error message will be created and no directory will /// be shown. /// </summary> /// <returns>Root path of the rive.</returns> private bool TryRestoreFromRootOnAnyDrive(out string restoredDirectory, out string restoredPage) { restoredDirectory = null; restoredPage = Settings.Default.showPageDefault.ToString(); try { DriveInfo[] drives = DriveInfo.GetDrives(); // try to get root directory on any fixed drive foreach (var drive in drives) { if (drive.IsReady && drive.DriveType == DriveType.Fixed) { restoredDirectory = drive.RootDirectory.FullName; } } // then, if there is not available fixed drives, try get root directory on any removable drive if (restoredDirectory is null) { foreach (var drive in drives) { if (drive.IsReady && drive.DriveType == DriveType.Removable) { restoredDirectory = drive.RootDirectory.FullName; } } } // if there is no available fixed or removable drive to start from, then return root directory for the first available drive. restoredDirectory ??= drives[0].RootDirectory.FullName; } catch (Exception e) { ErrorLogger.LogError(e); } // if restored directory is null then there is a problem with drives if (restoredDirectory is null) { CurrentDirectory = null; CurrentShownPage = 0; CurrentShownInfo = new Info( "Не удалось загрузить данные о папках и файлах: не оказалось ни одного доступного диска.", InfoType.Error ); return(false); } // if drives are ok, then path will be the root directory of some drive CurrentShownInfo = new Info( "Невозможно восстановить предыдущую сессию. Показана корневая папка диска.", InfoType.Warning ); return(true); }