2017-07-26 3 views
0

Ich habe eine WPF-Anwendung, die das Hinzufügen und Entfernen eines USB-Stick erkennen und geben Sie mir den Laufwerksnamen. im Moment habe ich dies:Laufwerksname von USB-Gerät bekommen

 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 
    } 

so weit dies funktioniert gut, zumindest die Erkennung von USB einfügen und entfernen.

Aber nachdem ich den Stick einfügen muss ich den Laufwerksnamen kennen, so dass ich meine Dateien auf den USB-Stick kopieren kann.

Leider ToDriveName zurück und '?' als Laufwerksbuchstabe.

Ich habe auch versucht dies:

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; 
    } 

dann erhalte ich eine E: \ anstelle des G: \ G: ist mein USB-Stick und E ist mein DVD-Laufwerk

Im Debugger Ich habe folgende Werte im Volumen: dbch_Size 0x000000d2
dbch_Devicetype 0x00000005
dbch_Unitmask 0xa5dcbf10
dbch_Reserved 0x00000000

+0

Löschen Sie diesen Kommentar und bearbeiten Sie Ihren Beitrag, um ihn einzuschließen. Kommentare formatieren keinen Code. –

Antwort

0

Casting zu DEV_BROADCAST_VOLUME macht nur Sinn, wenn dbch_DevicetypeDBT_DEVTYP_VOLUME (2) ist.

Sie benötigen

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

streng genommen zunächst DEV_BROADCAST_HDR verwenden sollten, testen Sie die Device, und nur dann, wenn es 2 ist, verwenden Sie DEV_BROADCAST_VOLUME.

+0

Danke, dass mein Problem gelöst hat – computermaus