友人や家族のために小さなバックアップ プログラムを作成しようとしていますが、できるだけ簡単に使用できるようにしたいと考えています。データのバックアップ先をユーザーに尋ねる必要はありません。コンピュータに接続されている最初の USB ハード ドライブを検索して使用したいだけです。ハードドライブの一意の ID を取得することも、次回バックアップを実行するための二重チェックとして、おそらく良い考えです。
5 に答える
RegisterDeviceNotification関数を使用する必要があります。これを行う方法についてのいくつかの指針があります。そしてもう1つのサンプルコード
このサンプルを使用して、すべての大容量記憶装置を列挙できます。一般的に、SetupDiXXXAPIを探します。
USBデバイスの動的な性質を考慮すると、通知メカニズムの使用は必須のIMHOであることに注意してください。自己分析デバイスがすでに切り離されているか、到着したばかりの新しいデバイスが欠落している場合があります。
ドライブの種類をテストするための優れた関数が 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: ドライブは CD-ROM ドライブです。
DRIVE_RAMDISK 6: ドライブは RAM ディスクです。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364939(v=vs.85).aspx
あなたの質問が 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 のいずれかを意味します。
補足として、UI の観点から、新しいドライブを初めて見つけたときに、それをユーザーに提示して、「これはバックアップに使用するドライブですか?」と尋ねることをお勧めします。そうしないと、たまたま差し込んだ USB キーのデータを誤って消去してしまう可能性が大きくなります。データを破壊するときほど、バックアップ プログラムの信頼性を損なうものはありません。:)
少し時間をかけて調べたところ、ハードドライブがリムーバブルかどうかを知るためのソリューションを提供する 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;
}
いくつかの情報はそれほど問題なく収集できます。
- GetDriveType を使用して最初のリムーバブル ドライブを見つけ、書き込み可能なメディアが存在するかどうかをテストします (CD ドライブはほとんど除外されます)。また、win32 経由でドライブ情報を照会するときに使用できる文字列をさらに確認することもできます。
- libusb を使用して、最初のストレージ クラスの USB デバイスがどこにあるかを確認します (フラッシュまたはハード ドライブである可能性が高い)。
- このC# の記事は、利用できる可能性のある win32 ディスク ドライブ クラスを示しています。
答えを見つけたらここに投稿してください!
-アダム