Как определить, что USB-накопитель подключен? - PullRequest
51 голосов
/ 14 мая 2011

Я хочу создать программу, которая обнаружит, подключен ли USB (или два или более) (и скопирует все содержимое в любую папку на жестком диске)

Есть идеи?У меня есть это,

using System.Runtime.InteropServices;

Но это не легкий путь (я верю).Я хочу что-то легкое.

У меня есть другая идея (если (папка существует), а затем скопировать) что-то - но может быть проблема с этим, и я хочу хорошее решение.

Также может существовать инструмент под названием SerialPort;я могу использовать это?Если да, то как мне его использовать?

Ответы [ 4 ]

60 голосов
/ 14 мая 2011

Это легко проверить на съемные устройства.Тем не менее, нет гарантии, что это устройство USB:

var drives = DriveInfo.GetDrives()
    .Where(drive => drive.IsReady && drive.DriveType == DriveType.Removable);

Это вернет список всех съемных устройств, которые в настоящее время доступны.Дополнительная информация:

21 голосов
/ 14 мая 2011

Определить, вставлен ли USB-накопитель, непросто.Тем не менее, это определенно возможно, и работа была сделана для вас.Вот две ссылки, каждая из которых содержит подробный ответ о том, как это сделать в C #:

http://www.codeproject.com/KB/system/DriveDetector.aspx

http://www.codeproject.com/Messages/2126647/Re-Csharp-USB-Detection.aspx

Любое решение должно работать нормально для вас.Вы можете адаптировать их под свои нужды.

Редактировать: Вот третье решение, если вам нужно больше вариантов (в основном они все одинаковые, но выбор хороший, верно?):

http://tempuzfugit.wordpress.com/2007/10/08/external-storage-unit-detection-with-c-in-net-usb-card-readers-etc/

11 голосов
/ 17 октября 2012

Вот код, который работает для меня, который является частью вышеуказанного сайта в сочетании с моими ранними испытаниями: http://www.codeproject.com/KB/system/DriveDetector.aspx

Это в основном заставляет вашу форму слушать сообщения Windows, фильтры для USB-накопителей и(cd-dvds), захватывает структуру lparam сообщения и извлекает букву диска.

protected override void WndProc(ref Message m)
    {

        if (m.Msg == WM_DEVICECHANGE)
        {
            DEV_BROADCAST_VOLUME vol = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));
            if ((m.WParam.ToInt32() == DBT_DEVICEARRIVAL) &&  (vol.dbcv_devicetype == DBT_DEVTYPVOLUME) )
            {
                MessageBox.Show(DriveMaskToLetter(vol.dbcv_unitmask).ToString());
            }
            if ((m.WParam.ToInt32() == DBT_DEVICEREMOVALCOMPLETE) && (vol.dbcv_devicetype == DBT_DEVTYPVOLUME))
            {
                MessageBox.Show("usb out");
            }
        }
        base.WndProc(ref m);
    }

    [StructLayout(LayoutKind.Sequential)] //Same layout in mem
    public struct DEV_BROADCAST_VOLUME
    {
        public int dbcv_size;
        public int dbcv_devicetype;
        public int dbcv_reserved;
        public int dbcv_unitmask;
    }

    private static char DriveMaskToLetter(int mask)
    {
        char letter;
        string drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //1 = A, 2 = B, 3 = C
        int cnt = 0;
        int pom = mask / 2;
        while (pom != 0)    // while there is any bit set in the mask shift it right        
        {        
            pom = pom / 2;
            cnt++;
        }
        if (cnt < drives.Length)
            letter = drives[cnt];
        else
            letter = '?';
        return letter;
    }

Не забудьте добавить это:

using System.Runtime.InteropServices;

и следующие константы:

    const int WM_DEVICECHANGE = 0x0219; //see msdn site
    const int DBT_DEVICEARRIVAL = 0x8000;
    const int DBT_DEVICEREMOVALCOMPLETE = 0x8004;
    const int DBT_DEVTYPVOLUME = 0x00000002;  
2 голосов
/ 19 февраля 2012

Microsoft API Code Pack.Класс ShellObjectWatcher.

...