Я пытаюсь написать небольшую резервную программу для друзей и семьи и хочу, чтобы она была максимально простой в использовании. Я не хочу спрашивать пользователя, где делать резервные копии своих данных, я просто хочу найти и использовать первый жесткий диск 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;
}
несколько частей информации могут быть собраны без особых проблем:
- Использование GetDriveType найти первый съемный диск, тест, если записываемые носители существует (что в значительной степени исключает CD диски). Может также хотеть посмотреть дальнейшие строки, которые доступны при запросе информации о диске через win32.
- Используйте libusb, чтобы увидеть, где первое устройство класса USB хранения (вероятно, будет вспышка или жесткий диск)
- Этот C# article указывает на win32 классов жестких дисков вы можете быть в состоянии подключиться.
Отправьте свой ответ здесь, когда найдете его!
-Adam
Благодарим за быстрый ответ. GetDriveInfo возвращает то же значение для фиксированного жесткого диска (диск C), как и для жесткого диска UDB; DRIVE_FIXED. Я попробовал его с USB-накопителем, и он сообщил об этом как DRIVE_REMOVABLE. –
Я знаю, что ваш вопрос помечен 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-накопитель (и достаточно большой) - Removable может означать либо Floppy, либо USB, according to the docs.
В качестве дополнительной заметки, с точки зрения пользовательского интерфейса, я предлагаю в первый раз, когда вы найдете новый диск, представите его пользователю и спросите: «Это тот диск, который вы хотите использовать для резервного копирования?». В противном случае существует большой потенциал для случайного удаления данных с ключа USB, который был подключен. Ничто не разрушает доверие к программе резервного копирования, например, когда оно уничтожает ваши данные. :)
Я предполагаю, что IO.DriveInfo совпадает с GetDriveInfo в win32 api. Если это так, он возвращает то же значение для жесткого диска USB, как и для жесткого диска (DRIVE_FIXED). –
Вам необходимо использовать функцию RegisterDeviceNotification. Here - это некоторые указания о том, как это сделать. И еще один sample code
Вы можете перечислить все запоминающие устройства массой, используя образец this. В целом найдите SetupDiXXX api's.
Обратите внимание, что принимая во внимание динамический характер USB-устройств, использование механизма уведомления является обязательным ИМХО. Вы можете найти свое самоанализирующее устройство, которое уже отсоединило или пропустило новое устройство, которое только что появилось.
Спасибо за указатель, но я не хочу обнаруживать, когда диск подключен или отключен, я хочу знать, подключен ли подключенный диск USB (он может быть подключен до запуска моей программы). –
Я нашел большую функцию в API Win32 для тестирования типа привода.
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: Привод представляет собой привод CD-ROM.
DRIVE_RAMDISK 6: Привод представляет собой RAM-диск.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364939(v=vs.85).aspx
Если у вас есть известный файл, расположенный в известном месте на вашем съемном диске (корневой), тогда вы можете просмотреть все буквы дисков, которые ищут этот файл. Когда вы его найдете, вы знаете букву диска. – BoltBait