ハードドライブがUSB経由で接続されているかどうかを検出する方法

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

  •  03-07-2019
  •  | 
  •  

質問

友人や家族のための小さなバックアッププログラムを作成しようとしていますが、できるだけ簡単に使用できるようにしたいと考えています。ユーザーにデータのバックアップ先を尋ねる必要はありません。コンピューターに接続されている最初のUSBハードドライブを検索して使用したいだけです。ハードドライブの一意のIDを取得することも、おそらく次回のバックアップ実行時の二重確認としてお勧めします。

役に立ちましたか?

解決 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のいずれかを意味します。ドキュメントによる

補足として、UIの観点から、新しいドライブを初めて見つけたらユーザーに提示し、「これはバックアップに使用するドライブですか?」と尋ねることをお勧めします。そうしないと、誤ってプラグインされたUSBキーのデータを誤って消去してしまう可能性があります。データを破壊するときのように、バックアッププログラムの信頼性を破壊するものは何もありません。 :)

RegisterDeviceNotification 関数を使用する必要があります。 ここは、その方法に関する指針ですそれを行うには。そしてもう1つのサンプルコード

このサンプルを使用して、すべての大容量記憶装置を列挙できます。一般に、SetupDiXXX APIを探します。

USBデバイスの動的な性質を考慮して、通知メカニズムを使用することは必須です。到着したばかりの新しいデバイスがすでに切り離されているか、欠落している自己分析デバイスを見つける場合があります。

面倒なことなくいくつかの情報を収集できます:

  • GetDriveTypeを使用して最初のリムーバブルドライブを見つけ、書き込み可能なメディアが存在するかどうかをテストします(CDドライブはほとんど除外されます)。また、win32を介してドライブ情報を照会するときに使用可能な文字列を確認することもできます。
  • libusbを使用して、最初のストレージクラスUSBデバイスがどこにあるかを確認します(おそらくフラッシュドライブまたはハードドライブです)
  • この C#の記事は、利用可能なwin32ディスクドライブクラスを示しています。

見つけたときに答えをここに投稿してください!

-アダム

ドライブの種類をテストするための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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top