How to detect a USB drive has been plugged in?
I want to build a program that detects if a usb (or two or more) are plugged in (and copy all contents to any folder on a hard disk)
Any ideas? I have this,
using System.Runtime.InteropServices;
But it is not the easy way (that I believe). I want something easy.
I have another idea (if (folder exist) then copy) something -- but there may be a problem with that, and I want a good solution.
There may also be a tool called SerialPort; can I use it? If so, how do I use it?
Solution 1:
It is easy to check for removable devices. However, there's no guarantee that it is a USB device:
var drives = DriveInfo.GetDrives()
.Where(drive => drive.IsReady && drive.DriveType == DriveType.Removable);
This will return a list of all removable devices that are currently accessible. More information:
-
The
DriveInfo
class (msdn documentation) -
The
DriveType
enumeration (msdn documentation)
Solution 2:
Here is a code that works for me, which is a part from the website above combined with my early trials: http://www.codeproject.com/KB/system/DriveDetector.aspx
This basically makes your form listen to windows messages, filters for usb drives and (cd-dvds), grabs the lparam structure of the message and extracts the drive letter.
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;
}
Do not forget to add this:
using System.Runtime.InteropServices;
and the following constants:
const int WM_DEVICECHANGE = 0x0219; //see msdn site
const int DBT_DEVICEARRIVAL = 0x8000;
const int DBT_DEVICEREMOVALCOMPLETE = 0x8004;
const int DBT_DEVTYPVOLUME = 0x00000002;
Solution 3:
Microsoft API Code Pack. ShellObjectWatcher class.