Pregunta

Estoy tratando de escribir un pequeño programa de respaldo para amigos y familiares y quiero que sea lo más sencillo de usar posible. No quiero tener que preguntar al usuario dónde hacer una copia de seguridad de sus datos, solo quiero buscar y usar el primer disco duro USB conectado a la computadora. Obtener la ID única del disco duro probablemente también sea una buena idea, como una segunda comprobación para la próxima vez que se ejecute la copia de seguridad.

¿Fue útil?

Solución 2

Pasé un poco de tiempo buscando y encontré una función llamada SetupDiEnumDeviceInfo que proporcionaba una solución para saber si un disco duro era extraíble o no, pero con esa información todavía no puedo (todavía) mapear lo que encuentro en un letra de la unidad!

Esto es lo que tengo hasta ahora (el siguiente código crea una 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;
}

Otros consejos

Sé que tu pregunta está etiquetada como Win32, pero esto es bastante simple con .NET:

foreach (IO.DriveInfo drive in IO.DriveInfo.GetDrives()) {
  if ((drive.DriveType == IO.DriveType.Removable)) {
    // this is a removable drive
  }
}

Consulte drive.Name y drive.VolumeLabel para obtener la etiqueta. También puede obtener el tamaño y adivinar que se trata de una memoria USB (y lo suficientemente grande): extraíble puede significar disquete o USB, de acuerdo con los documentos .

Como nota al margen, desde una perspectiva de la interfaz de usuario, sugeriría que la primera vez que encuentre una nueva unidad, se la presente al usuario y pregunte "¿es esta la unidad que desea usar para las copias de seguridad?". De lo contrario, existe un gran potencial para borrar accidentalmente los datos de una llave USB que se enchufó. Nada destruye la credibilidad de un programa de respaldo, como cuando destruye sus datos. :)

Debe usar la función RegisterDeviceNotification . Aquí hay algunos consejos sobre cómo para hacerlo. Y un código de ejemplo más

Puede enumerar todos los dispositivos de almacenamiento masivo utilizando esta muestra. En general, busque SetupDiXXX api's.

Tenga en cuenta que, teniendo en cuenta la naturaleza dinámica de los dispositivos USB, el uso del mecanismo de notificación es IMHO obligatorio. Es posible que encuentre su dispositivo de autoanálisis que ya se haya separado o que falte un dispositivo nuevo que acaba de llegar.

Se pueden recopilar algunos datos sin demasiados problemas:

  • Use GetDriveType para encontrar la primera unidad extraíble, compruebe si existen medios grabables (lo que en gran medida excluirá las unidades de CD). También es posible que desee consultar otras cadenas disponibles cuando consulta la información del disco a través de win32.
  • Use libusb para ver dónde está el primer dispositivo USB de clase de almacenamiento (probablemente será un flash o un disco duro)
  • Este artículo de C # apunta hacia las clases de unidades de disco win32 a las que podría acceder.

¡Publica tu respuesta aquí cuando la encuentres!

-Adam

Encontré una gran función en la API de Win32 para probar el tipo de unidad.

if( 2 == ::getDriveType( <driveletter> )){
  // its removable 
}

Valores de retorno de la función:

DRIVE_UNKNOWN 0: No se puede determinar el tipo de unidad.

DRIVE_NO_ROOT_DIR 1: la ruta raíz no es válida; por ejemplo, no hay un volumen montado en la ruta especificada.

DRIVE_REMOVABLE 2: La unidad tiene medios extraíbles; por ejemplo, una unidad de disquete, una unidad flash o un lector de tarjetas flash.

DRIVE_FIXED 3: La unidad tiene medios fijos; por ejemplo, una unidad de disco duro o una unidad flash.

DRIVE_REMOTE 4: La unidad es una unidad remota (red).

DRIVE_CDROM 5: La unidad es una unidad de CD-ROM.

DRIVE_RAMDISK 6: La unidad es un disco RAM.

http: // msdn .microsoft.com / en-us / library / windows / desktop / aa364939 (v = vs.85) .aspx

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top