Рассмотрим пример программы для извлечения USB накопителей с использованием WinAPI. Для извлечения накопителя будем использовать библиотеку «kernel32» и три ее функции. Функция DeviceIoControl отправляет управляющий код непосредственно указанному драйверу устройства, заставляя соответствующее устройство выполнить соответствующую операцию. Чтобы извлечь устройство, необходимы данные о дескрипторе устройства. DeviceIoControl может принять дескриптор конкретного устройства. Например, чтобы открыть дескриптор логического диска A: при помощи функции CreateFile, необходимо задать \.a:. Альтернативно, вы можете использовать имена \.PhysicalDrive0, \.PhysicalDrive1 и так далее, чтобы открывать дескрипторы на физические диски в системе.
Мы будем использовать букву устройства, которую присвоила операционная система. Для этого предварительно выполним поиск всех USB накопителей с использованием Windows Management Instrumentation (WMI), а так же для удобства выбора накопителя, будем заносить данные в компонент «СomboBox». Если операция извлечения завершается успешно, DeviceIoControl возвращает ненулевое значение, иначе возвращается ноль. После выполнения запроса на извлечение, необходимо с помощью функции CloseHandle закрыть дескриптор открытого объекта. Если функция завершается успешно, величина возвращаемого значения — не ноль.
Создайте проект Windows Form в Microsoft Visual Studio и добавьте на главную форму два компонента:
- ComboBox – Список доступных для извлечения USB накопителей;
- Button – Кнопка для извлечения выбранного USB накопителя.
У вас получится представленный ниже вариант:
Сделайте двойной клик по компоненту «button1» и перейдите в автоматически созданный метод «button1_Click». Добавьте в него приведенный ниже листинг вызова метода извлечения и обновления списка.
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 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 накопителей сразу при запуске вашей программы, добавьте в метод «Form1()» после строчки инициализации компонентов, вызов метода «LoadInfo();». Запустите проект, нажав на клавиатуре, клавишу «F5». Если у вас имеются уже вставленные в компьютер USB накопители, программа сразу отобразит их в списке и автоматически выберет первое из них.
Выберете необходимое вам для извлечения устройство и нажмите на кнопку «Извлечь». В случае если устройство не занято процессами, вы увидите соответствующее сообщение:
Или сообщение об ошибке:
Минусы данного решения:
- Необходимо чтобы флешка не была занята процессами;
- Не извлекает USB hard drive.
Ссылка для скачивания примера: Rusfolder.net
0.00 (0%) 0 votes
















