繁体   English   中英

从USB设备获取驱动器名称

[英]getting drive name from usb device

我有一个wpf applicatin,它将检测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

铸造到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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM