Как мне определить, подключен ли жесткий диск через USB?
-
03-07-2019 - |
Вопрос
Я пытаюсь написать небольшую программу резервного копирования для друзей и семьи и хочу, чтобы она была как можно более простой в использовании.Я не хочу спрашивать пользователя, куда сделать резервную копию его данных, я просто хочу найти и использовать первый жесткий диск USB, подключенный к компьютеру.Получение уникального идентификатора жесткого диска, вероятно, тоже было бы хорошей идеей, просто как двойная проверка при следующем запуске резервного копирования.
Решение 2
Я потратил немного времени, оглядываясь по сторонам, и обнаружил функцию 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;
}
Другие советы
Я знаю, что ваш вопрос помечен 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-ключа, который оказался подключенным. Ничто не разрушает доверие к программе резервного копирования, как, например, когда она уничтожает ваши данные. :) Р>
Вам необходимо использовать функцию RegisterDeviceNotification . Здесь приведены некоторые советы о том, как сделать это. И еще один пример кода
Вы можете перечислить все устройства хранения данных, используя этот пример . В общем, ищите API-интерфейсы SetupDiXXX. Р>
Обратите внимание, что принимая во внимание динамический характер USB-устройств, использование механизма уведомлений является обязательным IMHO. Вы можете найти ваше самоанализирующее устройство, которое уже отсоединилось или отсутствует новое устройство, которое только что прибыло. Р>
Несколько фрагментов информации можно собрать без особых проблем:
- Используйте GetDriveType, чтобы найти первый съемный дисковод, проверьте, существует ли записываемый носитель (что в значительной степени исключает CD-приводы).Возможно, также захочется просмотреть дополнительные строки, которые доступны при запросе информации о диске через win32.
- Используйте libusb, чтобы узнать, где находится USB-устройство первого класса хранения (скорее всего, это флэш-память или жесткий диск).
- Это Статья на C # указывает на классы дисководов win32, к которым вы могли бы подключиться.
Опубликуйте свой ответ здесь, когда найдете его!
-Адам
Я нашел отличную функцию в Win32 API для тестирования типа диска.
if( 2 == ::getDriveType( <driveletter> )){
// its removable
}
Возвращаемые значения функции:
DRIVE_UNKNOWN 0:Тип привода определить невозможно.
DRIVE_NO_ROOT_DIR 1:Недопустимый путь к корневому каталогу;например, по указанному пути нет тома, смонтированного.
ПРИВОД_УДАЛЯЕМЫЙ 2:Накопитель оснащен съемным носителем;например, дисковод для гибких дисков, флэш-накопитель или устройство для чтения флэш-карт.
ПРИВОД_ФИКСИРОВАН 3:На накопителе установлен носитель;например, жесткий диск или флэш-накопитель.
DRIVE_REMOTE УДАЛЕНИЕ ПРИВОДА 4:Диск является удаленным (сетевым) дисководом.
DRIVE_CDROM ПРИВОД_CDROM 5:Привод представляет собой дисковод для компакт-дисков.
ПРИВОДНОЙ_РАМДИСК 6:Привод представляет собой оперативный диск.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364939 (v=против 85).aspx