#c_sharp #net #windows
В Windows можно замонтировать диск, как папку. Например, когда все буквы под диски заняты. Как можно понять, что папка, с которой работает программа- это отдельный диск? Как узнать свободное место на этом замонтированном диске?
Ответы
Ответ 1
Как можно понять, что папка, с которой работает программа- это отдельный диск? Если нужно просто понять, что это не простая папка, то можно посмотреть список атрибутов на предмет наличия атрибута FileAttributes.ReparsePoint. Делается стандартным способом: var dInfo = new DirectoryInfo("FolderFullName"); if((dInfo.Attributes & FileAttributes.ReparsePoint) == 0) Console.WriteLine("Это самая обычная папка."); else Console.WriteLine("Эта папка не такая простая, как кажется!"); Проблема в том, что атрибут Reparse Point есть у всех объектов файловой системы специального назначения, будь то монтированные диски, символьные ссылки и прочие забавные объекты, о существовании и наличии которых вы, возможно, даже не догадывались (я тоже знаю и видел в живую далеко не все). Подробности можно почитать тут (к сожалению, родная документация не переведена) и тут(скромненько, но по-русски). Как узнать свободное место на этом замонтированном диске? А вот это уже интересная задача. DriveInfo.GetDrives() может показать только диски (вернее разделы дисков), которым назначена "Буква диска", иными словами, имеют изолированное дерево файловой системы. Если монтированному диску назначена и буква, и точка монтирования (да так тоже можно), то он, разумеется, будет в этом списке, но легче от этого не становится. Единственный гарантированный вариант получить необходимую информацию - запросить ее через WMI. Варианты с ручного низкоуровневого копания в содержимом "подозрительного" объекта ФС оставим для C++, да и антивирусы на такое иногда неадекватно реагируют или наоборот адекватно, но от этого не легче. За точки монтирования отвечает WMI-класс Win32_MountPoint. Объекты данного класса содержат две WMI-ссылки, на папку монтирования и логический диск. Получить их довольно легко. var namespaceScope = new ManagementScope(@"\\.\ROOT\CIMV2"); var diskQuery = new ObjectQuery("SELECT * FROM Win32_MountPoint"); var mgmtObjSearcher = new ManagementObjectSearcher(namespaceScope, diskQuery); ManagementObjectCollection mountPoints = mgmtObjSearcher.Get(); foreach (var mp in mountPoints) { //Получаем доступ к объекту Win32_Directory (папка к которой примонтирован диск) var dirObj = new ManagementObject(mp.Properties["Directory"].Value as string)); //Получаем доступ к объекту Win32_Volume (раздел диска который примонтирован к папке) var volumeObj = new ManagementObject(mp.Properties["Volume"].Value as string)); } Получение свойств самих объектов не представляет особой сложности, списки свойств можно найти тут: Win32_MountPoint, Win32_Volume, Win32_Directory Одно важное замечание, перед обращениям к свойствам объекта, надо убедиться, что объект получен без ошибок, или обернуть в try-catch, потому что объект возвращается даже при отсутствии доступа к папке или разделу, например при изъятом из DVD-привода диске. Объект будет находиться в невалидном состоянии и при обращении к свойствам произойдет исключение. Дальше уже дело техники: получаем точки монтирования, находим нужную, запрашиваем свойства раздела.
Комментариев нет:
Отправить комментарий