Как мне определить, подключен ли жесткий диск через USB?

StackOverflow https://stackoverflow.com/questions/220123

  •  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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top