Я пытаюсь написать небольшую программу резервного копирования для друзей и семьи и хочу, чтобы она была максимально простой в использовании. Я не хочу спрашивать пользователя, куда делать резервную копию их данных, я просто хочу найти и использовать первый жесткий диск USB, подключенный к компьютеру. Получение уникального идентификатора жесткого диска, вероятно, также будет хорошей идеей, просто как двойная проверка перед следующим запуском резервного копирования.
Как определить, подключен ли жесткий диск через USB?
Ответы (5)
Я знаю, что ваш вопрос помечен как Win32, но с .NET это довольно просто:
foreach (IO.DriveInfo drive in IO.DriveInfo.GetDrives()) {
if ((drive.DriveType == IO.DriveType.Removable)) {
// this is a removable drive
}
}
См. Drive.Name и drive.VolumeLabel для получения метки. Вы также можете узнать размер и сделать обоснованное предположение, что это USB-накопитель (и достаточно большой) - «Съемный» может означать либо дискету, либо USB, согласно документации.
В качестве примечания, с точки зрения пользовательского интерфейса, я бы посоветовал, когда вы впервые найдете новый диск, представить его пользователю и спросить: «Это тот диск, который вы хотите использовать для резервного копирования?». В противном случае существует большая вероятность случайного удаления данных на ключе USB, который случайно был подключен. Ничто так не подрывает доверие к программе резервного копирования, как когда она уничтожает ваши данные. :)
Я потратил немного времени на поиски и нашел функцию под названием SetupDiEnumDeviceInfo, которая действительно предоставила решение, чтобы узнать, был ли жесткий диск съемным или нет, но с этой информацией я все еще не могу (пока) сопоставить то, что я нашел, с буквой диска!
Вот что у меня есть (следующий код создает dll):
#include "stdafx.h"
#include <setupapi.h>
#include <devguid.h>
#include <cfgmgr32.h>
extern "C" __declspec(dllexport) int usb_hard_drives() {
HDEVINFO hdevinfo = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL, DIGCF_PRESENT);
if (hdevinfo == INVALID_HANDLE_VALUE) return -1;
DWORD MemberIndex = 0;
SP_DEVINFO_DATA sp_devinfo_data;
ZeroMemory(&sp_devinfo_data, sizeof(sp_devinfo_data));
sp_devinfo_data.cbSize = sizeof(sp_devinfo_data);
int c = 0;
while (SetupDiEnumDeviceInfo(hdevinfo, MemberIndex, &sp_devinfo_data)) {
DWORD PropertyRegDataType;
DWORD RequiredSize;
DWORD PropertyBuffer;
if (SetupDiGetDeviceRegistryProperty(hdevinfo, &sp_devinfo_data, SPDRP_CAPABILITIES, &PropertyRegDataType, (PBYTE)&PropertyBuffer, sizeof(PropertyBuffer), &RequiredSize)) {
if (PropertyBuffer && CM_DEVCAP_REMOVABLE == CM_DEVCAP_REMOVABLE) {
// do something here to identify the drive letter.
c++;
}
}
MemberIndex++;
}
SetupDiDestroyDeviceInfoList(hdevinfo);
return c;
}
Вам необходимо использовать функцию RegisterDeviceNotification. Здесь есть несколько указаний о том, как сделать это. И еще один образец кода
Вы можете перечислить все запоминающие устройства, используя этот образец. В общем, ищите SetupDiXXX api.
Обратите внимание, что, учитывая динамический характер USB-устройств, использование механизма уведомлений является обязательным ИМХО. Вы можете обнаружить, что ваше самоанализирующее устройство уже отсоединено или отсутствует новое, которое только что прибыло.
Несколько фрагментов информации можно собрать без особых проблем:
- Используйте GetDriveType, чтобы найти первый съемный диск, проверьте, существует ли записываемый носитель (что в значительной степени исключит приводы компакт-дисков). Возможно, вам также захочется посмотреть другие строки, которые доступны при запросе информации о диске через win32.
- Используйте libusb, чтобы узнать, где находится USB-устройство первого класса хранения (вероятно, это флэш-память или жесткий диск).
- Эта статья о C # указывает на классы дисков Win32, к которым вы, возможно, сможете подключиться.
Отправьте свой ответ здесь, когда найдете его!
-Адам
Я нашел в Win32 API отличную функцию для тестирования типа привода.
if( 2 == ::getDriveType( <driveletter> )){
// its removable
}
Возвращаемые значения функции:
DRIVE_UNKNOWN 0: тип привода не может быть определен.
DRIVE_NO_ROOT_DIR 1: корневой путь недействителен; например, по указанному пути не смонтирован том.
DRIVE_REMOVABLE 2: у накопителя есть съемный носитель; например, флоппи-дисковод, флэш-накопитель или устройство чтения флеш-карт.
DRIVE_FIXED 3: привод имеет фиксированный носитель; например, жесткий диск или флешка.
DRIVE_REMOTE 4: Диск является удаленным (сетевым) диском.
DRIVE_CDROM 5: дисковод является дисководом для компакт-дисков.
DRIVE_RAMDISK 6: Диск представляет собой RAM-диск.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364939(v=vs.85).aspx