问题
I am trying to write a little backup program for friends and family and want it to be as simple to use a possible. I don't want to have to ask the user where to backup their data to, I just want to search for and use the first USB hard drive connected to the computer. Obtaining the unique ID of the hard drive would probably be a good idea too, just as a double check for next time the backup runs.
回答1:
I know your question is tagged Win32, but this is quite simple with .NET:
foreach (IO.DriveInfo drive in IO.DriveInfo.GetDrives()) {
if ((drive.DriveType == IO.DriveType.Removable)) {
// this is a removable drive
}
}
See drive.Name and drive.VolumeLabel for getting the label. You can also get the size, and make an educated guess that it's a USB stick (and a big enough one) -- Removable can mean either Floppy or USB, according to the docs.
As a side note, from a UI perspective, I'd suggest the first time you find a new drive, present it to the user and ask "is this the drive you want to use for backups?". Otherwise, there is a big potential for accidentally wiping out data on a usb key that happened to be plugged in. Nothing destroys the credibility of a backup program like when it destroys your data. :)
回答2:
I spent a little time looking around and found a function called SetupDiEnumDeviceInfo which did provide a solution to know whether a hard drive was removable or not but with that information I still can't (yet) map what I find back to a drive letter!
Here's what I have so far (following code creates a 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;
}
回答3:
You need to use RegisterDeviceNotification function. Here is some pointers about how to do it. And one more sample code
You can enumerate all mass storage devices using this sample. In General look for SetupDiXXX api's.
Please note that taking in consideration dynamic nature of usb devices, using notification mechanism is mandatory IMHO. You might find your self analyzing device that already detached or missing new device that just arrived.
回答4:
A few pieces of information can be gathered without too much trouble:
- Use GetDriveType to find the first removeable drive, test if writeable media exists (which will largely rule out CD drives). May also want to look at further strings that are available when you query the drive information via win32.
- Use libusb to see where the first storage class USB device is (will likely be a flash or hard drive)
- This C# article points towards win32 disk drive classes you might be able to tap into.
Post your answer here when you find it!
-Adam
回答5:
I found a great function in the Win32 API for testing the type of drive.
if( 2 == ::getDriveType( <driveletter> )){
// its removable
}
Return values of function:
DRIVE_UNKNOWN 0: The drive type cannot be determined.
DRIVE_NO_ROOT_DIR 1: The root path is invalid; for example, there is no volume mounted at the specified path.
DRIVE_REMOVABLE 2: The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader.
DRIVE_FIXED 3: The drive has fixed media; for example, a hard disk drive or flash drive.
DRIVE_REMOTE 4: The drive is a remote (network) drive.
DRIVE_CDROM 5: The drive is a CD-ROM drive.
DRIVE_RAMDISK 6: The drive is a RAM disk.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364939(v=vs.85).aspx
来源:https://stackoverflow.com/questions/220123/how-do-i-detected-whether-a-hard-drive-is-connected-via-usb