2017-07-26 28 views
0

私は、USBスティックの追加と取り外しを検出し、ドライブ名を教えてくれるwpfアプリケーションを持っています。USBデバイスからドライブ名を取得

 protected override void OnSourceInitialized(EventArgs e) 
     { 
     base.OnSourceInitialized(e); 

     // Adds the windows message processing hook and registers USB device add/removal notification. 
     HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); 
     if (source != null) 
     { 
      IntPtr windowHandle = source.Handle; 
      source.AddHook(HwndHandler); 
      UsbNotification.RegisterUsbDeviceNotification(windowHandle); 
     } 
    } 

    // Convert to the Drive name (”D:”, “F:”, etc) 
    private string ToDriveName(int mask) 
    { 
     char letter; 
     string drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
     // 1 = A 
     // 2 = B 
     // 4 = C... 
     int cnt = 0; 
     int pom = mask/2; 
     while (pom != 0) 
     { 
      // while there is any bit set in the mask 
      // shift it to the righ...   
      pom = pom/2; 
      cnt++; 
     } 

     if (cnt < drives.Length) 
      letter = drives[cnt]; 
     else 
      letter = '?'; 

     string strReturn; 

     strReturn= letter + ":\\"; 
     return strReturn; 
    } 


    /// <summary> 
    /// Method that receives window messages. 
    /// </summary> 
    private IntPtr HwndHandler(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled) 
    { 
     if (msg == UsbNotification.WmDevicechange) 
     { 

      switch ((int)wparam) 
      { 
       case UsbNotification.DbtDeviceremovecomplete: 
        Usb_DeviceRemoved(); // this is where you do your magic 
        break; 
       case UsbNotification.DbtDevicearrival: 
        DEV_BROADCAST_VOLUME volume = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(lparam, typeof(DEV_BROADCAST_VOLUME)); 
        Usb_DeviceAdded(ToDriveName(volume.dbcv_unitmask)); // this is where you do your magic 
        break; 
      } 
     } 

     handled = false; 
     return IntPtr.Zero; 
    } 

    // Contains information about a logical volume. 
    [StructLayout(LayoutKind.Sequential)] 
    private struct DEV_BROADCAST_VOLUME 
    { 
     public int dbcv_size; 
     public int dbcv_devicetype; 
     public int dbcv_reserved; 
     public int dbcv_unitmask; 
    } 


    private void Usb_DeviceRemoved() 
    { 
     //todo something 
    } 
    private void Usb_DeviceAdded(string strDrive) 
    { 
     //todo something 
    } 

これまでのところ、これは正常に動作し、USBの少なくとも検出挿入し、削除します。私はこれを持っている現時点で 。

私はスティックを挿入した後、私はUSBスティックに自分のファイルをコピーできるようにドライブ名を知る必要があります。

残念ながら、ToDriveNameは '?'を返します。ドライブレターとして。私もこの試みた

private string ToDriveName(int Mask) 
    { 
     int i = 0; 
     for (i = 0; i < 26; ++i) 
     { 
      if ((Mask & 0x1) == 0x1) break; 
      Mask = Mask >> 1; 
     } 
     char cLetter= (char)(Convert.ToChar(i) + 'A'); 

     string strReturn; 

     strReturn= cLetter + ":\\"; 
     return strReturn; 
    } 

を、私はEを得る:代わりにGの\:\ G:私のUSBスティックであり、Eは、私が持っているデバッガで私のDVDドライブ

ですボリュームに次の値: dbch_Size 0x000000d2
dbch_Devicetype 0x00000005
dbch_Unitmask 0xa5dcbf10
dbch_Reserved 0x00000000の

+0

コメントを削除し、投稿を編集して投稿します。コメントはコードを書式化しません。 –

答えて

0

DEV_BROADCAST_VOLUMEへのキャストは、dbch_DevicetypeDBT_DEVTYP_VOLUME(2)の場合にのみ意味を持ちます。

あなたは、あなたが最初にDEVICETYPEをテストし、DEV_BROADCAST_HDRを使用する必要があります

if (volume.dbch_Devicetype == 2) Usb_DeviceAdded(ToDriveName(volume.dbcv_unitmask)); 

は、厳密に言えば必要で、それが2のときにのみ、 DEV_BROADCAST_VOLUMEを使用しています。

+0

問題を解決していただきありがとうございます – computermaus

関連する問題