Рассмотрим пример программы для извлечения USB накопителей с использованием WinAPI. Для извлечения накопителя будем использовать библиотеку «kernel32» и три ее функции. Функция DeviceIoControl отправляет управляющий код непосредственно указанному драйверу устройства, заставляя соответствующее устройство выполнить соответствующую операцию. Чтобы извлечь устройство, необходимы данные о дескрипторе устройства. DeviceIoControl может принять дескриптор конкретного устройства. Например, чтобы открыть дескриптор логического диска A: при помощи функции CreateFile, необходимо задать \\.\a:. Альтернативно, вы можете использовать имена \\.\PhysicalDrive0, \\.\PhysicalDrive1 и так далее, чтобы открывать дескрипторы на физические диски в системе.
Мы будем использовать букву устройства, которую присвоила операционная система. Для этого предварительно выполним поиск всех USB накопителей с использованием Windows Management Instrumentation (WMI), а так же для удобства выбора накопителя, будем заносить данные в компонент «СomboBox». Если операция извлечения завершается успешно, DeviceIoControl возвращает ненулевое значение, иначе возвращается ноль. После выполнения запроса на извлечение, необходимо с помощью функции CloseHandle закрыть дескриптор открытого объекта. Если функция завершается успешно, величина возвращаемого значения - не ноль.
Создайте проект Windows Form в Microsoft Visual Studio и добавьте на главную форму два компонента:
Или сообщение об ошибке:Минусы данного решения:
Мы будем использовать букву устройства, которую присвоила операционная система. Для этого предварительно выполним поиск всех USB накопителей с использованием Windows Management Instrumentation (WMI), а так же для удобства выбора накопителя, будем заносить данные в компонент «СomboBox». Если операция извлечения завершается успешно, DeviceIoControl возвращает ненулевое значение, иначе возвращается ноль. После выполнения запроса на извлечение, необходимо с помощью функции CloseHandle закрыть дескриптор открытого объекта. Если функция завершается успешно, величина возвращаемого значения - не ноль.
Создайте проект Windows Form в Microsoft Visual Studio и добавьте на главную форму два компонента:
- ComboBox – Список доступных для извлечения USB накопителей;
- Button – Кнопка для извлечения выбранного USB накопителя.
EjectDrive(kvp[comboBox1.SelectedIndex]); //Обновляем список накопителей LoadInfo();Добавьте в листинг главной формы, приведенный ниже код извлечения USB накопителя.
const int OPEN_EXISTING = 3; const uint GENERIC_READ = 0x80000000; const uint GENERIC_WRITE = 0x40000000; const uint IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808; [System.Runtime.InteropServices.DllImport("kernel32")] private static extern int CloseHandle(IntPtr handle); [System.Runtime.InteropServices.DllImport("kernel32")] private static extern int DeviceIoControl (IntPtr deviceHandle, uint ioControlCode, IntPtr inBuffer, int inBufferSize, IntPtr outBuffer, int outBufferSize, ref int bytesReturned, IntPtr overlapped); [System.Runtime.InteropServices.DllImport("kernel32")] private static extern IntPtr CreateFile (string filename, uint desiredAccess, uint shareMode, IntPtr securityAttributes, int creationDisposition, int flagsAndAttributes, IntPtr templateFile); ListДля получения списка букв USB накопителей сразу при запуске вашей программы, добавьте в метод «Form1()» после строчки инициализации компонентов, вызов метода «LoadInfo();». Запустите проект, нажав на клавиатуре, клавишу «F5». Если у вас имеются уже вставленные в компьютер USB накопители, программа сразу отобразит их в списке и автоматически выберет первое из них. Выберете необходимое вам для извлечения устройство и нажмите на кнопку «Извлечь». В случае если устройство не занято процессами, вы увидите соответствующее сообщение:kvp; //Получение списка букв USB накопителей private void UsbDiskList() { string diskName = string.Empty; kvp = new List (); //предварительно очищаем список comboBox1.Items.Clear(); //Получение списка накопителей подключенных через интерфейс USB foreach (System.Management.ManagementObject drive in new System.Management.ManagementObjectSearcher( "select * from Win32_DiskDrive where InterfaceType='USB'").Get()) { //Получаем букву накопителя foreach (System.Management.ManagementObject partition in new System.Management.ManagementObjectSearcher( "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + drive["DeviceID"] + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get()) { foreach (System.Management.ManagementObject disk in new System.Management.ManagementObjectSearcher( "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + partition["DeviceID"] + "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get()) { //Получение буквы устройства diskName = disk["Name"].ToString().Trim(); comboBox1.Items.Add(diskName + " (" + drive["Model"] + ")"); kvp.Add(diskName); } } } } //метод для извлечения USB накопителя static void EjectDrive(string driveLetter) { string path = "\\\\.\\" + driveLetter; IntPtr handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); if ((long)handle == -1) { MessageBox.Show("Невозможно извлечь USB устройство!", "Извлечение USB накопителей", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } int dummy = 0; DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, ref dummy, IntPtr.Zero); int returnValue = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, ref dummy, IntPtr.Zero); CloseHandle(handle); MessageBox.Show("USB устройство, успешно извлечено!", "Извлечение USB накопителей",MessageBoxButtons.OK,MessageBoxIcon.Information); } private void LoadInfo() { //Загрузка букв USB накопителей при запуске программы UsbDiskList(); //Выбор первого устройства в списке comboBox1.SelectedIndex = 0; }
Или сообщение об ошибке:Минусы данного решения:
- Необходимо чтобы флешка не была занята процессами;
- Не извлекает USB hard drive.
Ссылка для скачивания примера: Rusfolder.net
Сообщение об извлечении появляется, но флешка все равно остается в системе.
ОтветитьУдалить