web-dev-qa-db-ja.com

USBドライブが接続されたことを検出する方法は?

USB(または2つ以上)が接続されているかどうかを検出する(およびすべてのコンテンツをハードディスク上の任意のフォルダーにコピーする)プログラムを作成したい

何か案は?私はこれを持っています

using System.Runtime.InteropServices;

しかし、それは簡単な方法ではありません(私は信じています)。簡単なものが欲しい。

私は別のアイデアを持っています((フォルダが存在する場合)コピーする)-それに問題がある可能性があり、良い解決策が欲しいです。

SerialPortと呼ばれるツールもあります。使用できますか?その場合、どのように使用しますか?

53
angel

リムーバブルデバイスの確認は簡単です。ただし、USBデバイスであるという保証はありません。

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

これにより、現在アクセス可能なすべてのリムーバブルデバイスのリストが返されます。詳しくは:

61
Elian Ebbing

USBドライブが挿入されているかどうかを検出するのは簡単ではありません。しかし、それは間違いなく可能であり、作業はあなたのために行われました。 C#でこれを行う方法に関する回答の詳細を示す2つのリンクを次に示します。

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

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

どちらの解決策でもうまくいくはずです。ニーズに合わせて調整できます。

編集:これは、より多くのオプションが必要な場合の3番目のソリューションです(基本的にはすべて同じですが、選択は良いでしょう?):

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

21
IAmTimCorey

これは私のために機能するコードです。これは上記のWebサイトの一部であり、私の初期のトライアルと組み合わせたものです。 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;  
11
Onsightfree

Microsoft APIコードパック。 ShellObjectWatcherクラス。

2
Mark