天天看点

C#自动监测U盘插入自动后台静默复制U盘文件到本地

 今天调试串口,因为串口不支持热插拔,所以一直无法做的太智能化。但是突然想到U盘支持热插拔,就DIY了一个自动监控U盘是否插入电脑,插入启动并且静默复制U盘文件至本地文件夹。

 通过重写WndProc函数,用于捕获系统运行返回消息。什么是WndProc函数?Wndproc是Windows操作系统向应用程序发送一系列消息之一,每个窗口会有一个窗口过程的回调函数,分别是窗口句柄、消息ID、

WPARAM、LPARAM。

先上图:

C#自动监测U盘插入自动后台静默复制U盘文件到本地

第一步:重写 protected override void WndProc(ref Message m)函数。 

public const int WM_DEVICECHANGE = 0x219;//通知应用程序更改设备或计算机的硬件配置。
    public const int DBT_DEVICEARRIVAL = 0x8000;//U盘插入
    public const int DBT_CONFIGCHANGECANCELED = 0x0019;
    public const int DBT_CONFIGCHANGED = 0x0018;//当前配置发生了变化 
    public const int DBT_CUSTOMEVENT = 0x8006;
    public const int DBT_DEVICEQUERYREMOVE = 0x8001;
    public const int DBT_DEVICEQUERYREMOVEFAILED = 0x8002;
    public const int DBT_DEVICEREMOVECOMPLETE = 0x8004;//设备已经被清除
    public const int DBT_DEVICEREMOVEPENDING = 0x8003;
    public const int DBT_DEVICETYPESPECIFIC = 0x8005;//与设备有关的事件
    public const int DBT_DEVNODES_CHANGED = 0x0007;//设备节点发生了变化
    public const int DBT_QUERYCHANGECONFIG = 0x0017;
    public const int DBT_USERDEFINED = 0xFFFF;
           
protected override void WndProc(ref Message m)
 {
    try
    {
        string UDeskName = "";
        if (m.Msg == WM_DEVICECHANGE)//通知应用程序更改设备或计算机的硬件配置。      
        {
            switch (m.WParam.ToInt32())
            {
                case WM_DEVICECHANGE://通知应用程序更改设备或计算机的硬件配置。
                     break;
                case DBT_DEVICEARRIVAL://U盘插入
                     DriveInfo[] s = DriveInfo.GetDrives();
                     foreach (DriveInfo drive in s)
                     {
                        if (drive.DriveType == DriveType.Removable)
                        {
                            UDeskName = drive.Name.ToString();
                            ShowInfo("【系统消息】U盘已插入,盘符为: " + UDeskName + GetNowTime());
                            string[] para = new string[] { UDeskName, "D:\\U盘\\" };
                            Thread t = new Thread(new ParameterizedThreadStart(CopyMethod));
                            t.Start(para);
                            break;
                        }
                     }
                     break;
                case DBT_CONFIGCHANGECANCELED:
                     break;
                case DBT_CONFIGCHANGED:
                     break;
                case DBT_CUSTOMEVENT:
                     break;
                case DBT_DEVICEQUERYREMOVE://允许清除被请求的设备。任何应用程序都可以拒绝这个请求并取消清除操作。  
                     break;
                case DBT_DEVICEQUERYREMOVEFAILED://清除设备的请求被取消了
                     break;
                case DBT_DEVICEREMOVECOMPLETE: //U盘卸载
                     ShowInfo("【系统消息】U盘已拔出" + GetNowTime());
                     break;
                case DBT_DEVICEREMOVEPENDING://设备将要被清除。不能拒绝
                     break;
                case DBT_DEVICETYPESPECIFIC:
                     break;
                case DBT_DEVNODES_CHANGED://设备变化时
                     break;
                case DBT_QUERYCHANGECONFIG:
                     break;
                case DBT_USERDEFINED:
                     break;
                default:
                     break;
            }
        }
    }
    catch (Exception ex)
    {
    }
    base.WndProc(ref m);
}
           

第二步:当Wndproc返回消息为:DBT_DEVICEARRIVAL = 0x8000,即监测到U盘已经插入。则开启一个线程,复制U盘文件至本地。

由于带参数的线程一个只能传一个参数,而我这里传了U盘路径和复制到本地的目标路径。这里解决方法有两种:

 第一种:比如自己写一个类,讲2个参数封装在类里;

 第二种:我写了一个方法。在方法里调用复制循环复制文件的方法。

private void CopyMethod(object obj)
        {
            //此处对传进来的参数进行处理
            string[] strPath = (string[])obj;
            //调用CopyFolder方法
            CopyMoveDisk(strPath[0], strPath[1]);
        }
           

第三步:写复制文件和文件夹的方法

public void CopyMoveDisk(string from, string to)
        {
            try
            {
                if (!Directory.Exists(to))
                    Directory.CreateDirectory(to);
                // 复制子文件夹
                foreach (string sub in Directory.GetDirectories(from))
                {
                    if (!sub.Contains("System Volume Information"))
                    {
                        CopyMoveDisk(sub + "\\", to + Path.GetFileName(sub) + "\\");
                        ShowInfo("复制文件夹: [" + sub + "]" + "成功!" + GetNowTime());
                    }
                        
                }
                // 复制文件
                foreach (string file in Directory.GetFiles(from))
                {
                    File.Copy(file, to + Path.GetFileName(file), true);
                    ShowInfo("复制文件: [" + file + "]" + "成功!" + GetNowTime());
                }               
            }
            catch (Exception ex)
            {
                ShowInfo("【系统消息】复制文件出错" + GetNowTime());
            }
        }
           

完整代码下载地址:http://download.csdn.net/download/wangzhichunnihao/10246814

参考博客:http://blog.csdn.net/galaft/article/details/2448546