Как определить, подключен ли жесткий диск через USB? - PullRequest
3 голосов
/ 21 октября 2008

Я пытаюсь написать небольшую программу резервного копирования для друзей и семьи и хочу, чтобы она была максимально простой в использовании. Я не хочу спрашивать пользователя, куда делать резервные копии своих данных, я просто хочу найти и использовать первый жесткий диск USB, подключенный к компьютеру. Также было бы неплохо получить уникальный идентификатор жесткого диска, так же как и двойная проверка для следующего запуска резервного копирования.

Ответы [ 5 ]

1 голос
/ 22 октября 2008

Я потратил немного времени, оглядываясь по сторонам, и обнаружил функцию 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;
}
1 голос
/ 21 октября 2008

Я знаю, что ваш вопрос помечен 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-ключа, который оказался подключенным. Ничто не разрушает доверие к программе резервного копирования, как, например, когда она уничтожает ваши данные. :)

1 голос
/ 21 октября 2008

Вам необходимо использовать функцию RegisterDeviceNotification . Здесь - несколько советов о том, как это сделать. И еще один пример кода

Вы можете перечислить все устройства хранения данных, используя этот образец. В общем, ищите API-интерфейсы SetupDiXXX.

Обратите внимание, что принимая во внимание динамический характер USB-устройств, использование механизма уведомлений является обязательным IMHO. Вы можете найти ваше самоанализирующее устройство, которое уже отсоединилось или отсутствует новое устройство, которое только что прибыло.

0 голосов
/ 29 августа 2012

Я нашел отличную функцию в 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

0 голосов
/ 21 октября 2008

Несколько частей информации могут быть собраны без особых проблем:

  • Используйте GetDriveType, чтобы найти первый съемный диск, проверьте, существует ли записываемый носитель (который в значительной степени исключает CD-дисководы). Может также потребоваться просмотреть дополнительные строки, которые доступны при запросе информации о диске через win32.
  • Используйте libusb, чтобы увидеть, где находится первое USB-устройство хранения данных (скорее всего, это флэш-память или жесткий диск)
  • Эта статья C # указывает на классы дисков win32, к которым вы можете подключиться.

Опубликуйте свой ответ здесь, когда найдете его!

-Adam

...