网上有些代码是在U盘插入时遍历电脑所有盘符,会有些问题,如已有1个U盘,再插入一个U盘,无法区分最近插入是那个。
U盘插入时,遍历U盘所有盘符,查找指定目录,有则备份,无则提示。代码如下:
[StructLayout(LayoutKind.Sequential)]
private 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
}
private const int WM_DEVICECHANGE = 0x0219;
private const int DBT_DEVICEARRIVAL = 0x8000;
private const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
private const int DBT_DEVTYP_VOLUME = 0x00000002;// 逻辑卷标
protected override void WndProc(ref Message m)
{
try
{
if (m.Msg == WM_DEVICECHANGE)
{
int state = m.WParam.ToInt32();
switch (state)
{
case DBT_DEVICEARRIVAL: //U盘插入
case DBT_DEVICEREMOVECOMPLETE: //U盘拔出
if (Marshal.ReadInt32(m.LParam, 4) == DBT_DEVTYP_VOLUME) //设备类型为有盘符
{
DEV_BROADCAST_VOLUME vol;
vol = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));
if (vol.dbcv_flags == 0) //为硬盘或U盘
{
if (state == DBT_DEVICEARRIVAL)
{
Message("U盘插入。");
bool has备份目录 = false;
uint mask = vol.dbcv_unitmask;
for (int i = 0; i < 26; i++, mask >>= 1)
{
if ((mask & 1) == 1)
{
string strPath = $@"{(char)(i + 'A')}:\NHDataBackup\";
if (Directory.Exists(strPath))
{
has备份目录 = true;
new Thread(Copy).Start(strPath);
}
}
}
if (!has备份目录)
{
Error($"U盘根目录应有'NHDataBackup'文件夹,才能完成自动备份。");
}
}
else
{
Message("U盘拔出。");
}
}
}
break;
default:
break;
}
}
}
catch (Exception ex)
{
Error(ex.Message);
}
base.WndProc(ref m);
}
private void Copy(object path)
{
string strPath = $"{(string)path}db{DateTime.Now:yyyyMMddHHmmss}.mdb";
try
{
File.Copy(Access.AccessPath, strPath);
Message($"数据已备份到{strPath}");
}
catch (IOException e)
{
Error(e.Message);
}
}