2017-07-26 155 views
0

我有一個wpf應用程序,它應檢測添加和移除USB棒並給我驅動器名稱。 此刻我有這樣的:從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:是我的U盤和E是我的DVD驅動器

在調試器中我有在體積以下值: dbch_Size 0x000000d2
dbch_Devicetype 0x00000005
dbch_Unitmask 0xa5dcbf10
dbch_Reserved 00000000

+0

刪除該評論並編輯您的帖子以包含它。評論不會格式化代碼。 –

回答

0

鑄造到DEV_BROADCAST_VOLUME僅在dbch_DevicetypeDBT_DEVTYP_VOLUME(2)時纔有意義。

你需要

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

嚴格地說,你應該先用DEV_BROADCAST_HDR,測試設備類型,只有當它是2,使用DEV_BROADCAST_VOLUME

+0

謝謝你解決了我的問題 – computermaus