Windows系统下,每当外部设备有变动时都会向所有窗体发送一个消息,我们根据这点可以让程序检测出例如U盘插拔的信号,在C#代码中实现如下:
[StructLayout(LayoutKind.Sequential)]
struct DEV_BROADCAST_HDR
{
public UInt32 dbch_size;//dbch_size表示结构体实例的字节数
public UInt32 dbch_devicetype; //dbch_devicetype字段值等于DBT_DEVTYP_VOLUME时,表示当前设备是逻辑驱动器
public UInt32 dbch_reserved;
}
[StructLayout(LayoutKind.Sequential)]
struct DEV_BROADCAST_VOLUME
{
public UInt32 dbcv_size;
public UInt32 dbcv_devicetype;
public UInt32 dbcv_reserved;
public UInt32 dbcv_unitmask;//dbcv_unitmask 字段表示当前改变的驱动器掩码,第一位表示驱动器号A,第二位表示驱动器号B,第三位表示驱动器号C,以此类推……
public UInt16 dbcv_flags;//dbcv_flags 表示驱动器的类别,如果等于1,则是光盘驱动器;如果是2,则是网络驱动器;如果是硬盘、U盘则都等于0
}
protected override void DefWndProc(ref Message m)
{
//textBox1.AppendText("Message = " + m + "\r\n");
if (m.Msg == 0x0219)//WM_DEVICECHANGE
{
//textBox1.AppendText("m.WParam = " + m.WParam.ToInt32() + "\r\n");
switch (m.WParam.ToInt32())
{
case 0x8000://DBT_DEVICEARRIVAL 有设备插入
{
DEV_BROADCAST_HDR dbhdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HDR));
if (dbhdr.dbch_devicetype == 0x00000002)//DBT_DEVTYP_VOLUME
{
DEV_BROADCAST_VOLUME dbv = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));
if (dbv.dbcv_flags == 0)
{
//U盘插入操作
Console.WriteLine("检测到U盘插入!");
}
}
break;
}
case 0x8004://DBT_DEVICEREMOVECOMPLETE 有设备拔出
{
DEV_BROADCAST_HDR dbhdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HDR));
if (dbhdr.dbch_devicetype == 0x00000002)//DBT_DEVTYP_VOLUME
{
DEV_BROADCAST_VOLUME dbv = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));
if (dbv.dbcv_flags == 0)
{
Console.WriteLine("检测到U盘拔出!");
}
}
break;
}
}
}
base.DefWndProc(ref m);
}
其中我注释掉的几行都是供测试用的语句,这里是只对WParam参数为0x8000(设备插入)和0x8004(设备拔出)做了判断,大家还可以取消 //textBox1.AppendText("Message = " + m + "\r\n");注释来自行测试其他操作发送的指令,如鼠标移动时也会发送一串消息,这里分享的是一个思路,觉得有用的话别忘了点赞关注哦~