c# 获取移动硬盘信息、监听移动设备的弹出与插入事件

原文 http://www.cnblogs.com/coolkiss/p/3328825.html

备忘一下改功能,主要通过WMI来实现,对于监听外接设备的弹出和插入事件一开始使用IntPtr WndProc事件,但是当监听到改事件时,同过WMI来获取设备,有时候还不能获取到,因此还是使用WqlEventQuery 来监听WMI的变化。下列是主要代码片段

 

1. 获取硬盘的固件序列号,盘序列号(由系统指派的唯一ID),总容量,剩余容量, 盘符,盘名称等信息

复制代码
private static List<DriverBase> GetDrivers(InterfaceType type, string partitionName)

        {

            List<DriverBase> drivers = new List<DriverBase>();

            string strQuery = "select * from Win32_DiskDrive";

            if(type == InterfaceType.USB)

                strQuery += " Where InterfaceType = 'USB'";

            else if (type == InterfaceType.IDE)

                strQuery += " Where InterfaceType = 'IDE'";

            

            SelectQuery sq = new SelectQuery(strQuery);

            ManagementObjectSearcher mos = new ManagementObjectSearcher(sq);

            foreach (ManagementObject disk in mos.Get())

            {

                string DeviceID = disk["DeviceID"].ToString();

                foreach (ManagementObject partition in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + DeviceID + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get())

                {

                    string query = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + partition["DeviceID"] + "'} WHERE AssocClass = Win32_LogicalDiskToPartition";

                    foreach (ManagementObject disk1 in new ManagementObjectSearcher(query).Get())

                    {

                        DriverBase b = new DriverBase();

                        string diviceID = disk1["DeviceID"].ToString().Trim();

                        if (!IsNTFS(diviceID))

                        {

                            continue;

                        }

                        string Name = disk1["Name"].ToString().Trim();

                        string freeSpace = disk1["FreeSpace"].ToString().Trim();

                        string size = disk1["Size"].ToString().Trim();

                        if (!string.IsNullOrEmpty(partitionName) && Name.ToUpper() != partitionName.ToUpper())

                        {

                            continue;

                        }

                        b.DriverName = Helper.DriverHelper.GetVolumnLabel(diviceID);

                        b.TotalSpace = double.Parse(size);

                        b.FreeSpace = double.Parse(freeSpace);

                        b.DeviceID = diviceID;

                        b.IsOverload = (b.TotalSpace - b.FreeSpace) / b.TotalSpace > 0.7;

                        b.SerialNum = disk["SerialNumber"] == null ? "" : disk["SerialNumber"].ToString().Trim();

                        if (string.IsNullOrEmpty(b.SerialNum))

                        {

                            string pnpdeviceid = disk["PNPDeviceID"] == null ? "" : disk["PNPDeviceID"].ToString().Trim();

                            if (!string.IsNullOrEmpty(pnpdeviceid))

                                b.SerialNum = parseSerialFromDeviceID(pnpdeviceid);

                        }

                        b.VolumeSerialNum = GetVolumeSerialNumber(diviceID);

                        if(!string.IsNullOrEmpty(b.SerialNum))

                            drivers.Add(b);

                        

                    }

                }

            }

            return drivers;

        }





    /// <summary>

        /// Get driver by partition name

        /// </summary>

        /// <param name="name">name should be "C:" or "D"</param>

        /// <returns></returns>

        public static DriverBase GetDriverByName(string name)

        {

            string strQuery = "select * from Win32_LogicalDisk where DeviceID='" + name + "'";

            

            SelectQuery sq = new SelectQuery(strQuery);

            ManagementObjectSearcher mos = new ManagementObjectSearcher(sq);

            DriverBase driver = null;

            foreach (ManagementObject disk in mos.Get())

            {

                driver = new DriverBase();

                driver.DeviceID = disk["DeviceID"].ToString();

                driver.DriverName = disk["VolumeName"].ToString();

                driver.VolumeSerialNum = disk["VolumeSerialNumber"].ToString();

                driver.TotalSpace = double.Parse(disk["Size"].ToString());

                if (disk["FileSystem"].ToString() != "NTFS")

                {

                    return null;

                }

                driver.FreeSpace = double.Parse(disk["FreeSpace"].ToString());

                driver.IsOverload = (driver.TotalSpace - driver.FreeSpace) / driver.TotalSpace > 0.7;

                driver.SerialNum = GetSeiralByDevice(driver.DeviceID);

                if (!string.IsNullOrEmpty(driver.SerialNum))

                    return driver;

            }

            return driver;

            //return DriverBase.GetDrivers(InterfaceType.ALL, name).FirstOrDefault();

        }



   // fix cannot get serial number of some flash driver of WMI

        // http://stackoverflow.com/questions/1176053/read-usb-device-serial-number-in-c-sharp/1176089#1176089

        private static string parseSerialFromDeviceID(string deviceId)

        {

            string[] splitDeviceId = deviceId.Split('\\');

            string[] serialArray;

            string serial;

            int arrayLen = splitDeviceId.Length - 1;



            serialArray = splitDeviceId[arrayLen].Split('&');

            serial = serialArray[0];



            return serial;

        }
复制代码

 

2. 下列代码段用于监听新增或删除外接设备

复制代码
  public class UsbDriverWatcher

    {

        ManagementEventWatcher eventWatcher;

        ManagementEventWatcher delEventWatcher;

        public void Start()

        {

            try

            {

                //DriveType

                //Value        Meaning 

                //0        Unknown

                //1        No Root Directory

                //2        Removable Disk

                //3        Local Disk

                //4        Network Drive

                //5        Compact Disc

                //6        RAM Disk

                WqlEventQuery query = new WqlEventQuery("__InstanceCreationEvent", new TimeSpan(0, 0, 1), @"TargetInstance ISA 'Win32_LogicalDisk'");



                ConnectionOptions opt = new ConnectionOptions();

                opt.EnablePrivileges = true;

                opt.Authority = null;

                opt.Authentication = AuthenticationLevel.Default;



                ManagementScope scope = new ManagementScope("\\root\\CIMV2", opt);



                eventWatcher = new ManagementEventWatcher(scope, query);

                eventWatcher.EventArrived += new EventArrivedEventHandler(eventWatcher_EventArrived);

                eventWatcher.Start();



                WqlEventQuery delQuery = new WqlEventQuery("__InstanceDeletionEvent", new TimeSpan(0, 0, 1), @"TargetInstance ISA 'Win32_LogicalDisk'");



                ConnectionOptions opt2 = new ConnectionOptions();

                opt2.EnablePrivileges = true;

                opt2.Authority = null;

                opt2.Authentication = AuthenticationLevel.Default;



                ManagementScope scope2 = new ManagementScope("\\root\\CIMV2", opt2);



                delEventWatcher = new ManagementEventWatcher(scope2, delQuery);

                delEventWatcher.EventArrived += new EventArrivedEventHandler(delEventWatcher_EventArrived);

                delEventWatcher.Start();

            }

            catch (Exception ex)

            {

            }

        }



        public void Stop()

        {

            if (eventWatcher != null)

            {

                eventWatcher.Stop();

                delEventWatcher.Stop();

            }

        }



        void eventWatcher_EventArrived(object sender, EventArrivedEventArgs e)

        {

            ManagementBaseObject wmiDevice = (ManagementBaseObject)e.NewEvent["TargetInstance"];

            String driveName = (string)wmiDevice["DeviceID"];

            //string volumeName =  wmiDevice.Properties["VolumeName"].Value == null  ? "":wmiDevice.Properties["VolumeName"].Value.ToString();

            if (!string.IsNullOrEmpty(driveName))

            {

                if (OnDeviceChanged != null)

                {

                    OnDeviceChanged(null, new DeviceChangedEventArgs()

                    {

                        DriverName = driveName,

                        Action = DeviceChangedAction.Add

                    });

                }

            }

        }



        void delEventWatcher_EventArrived(object sender, EventArrivedEventArgs e)

        {

            ManagementBaseObject wmiDevice = (ManagementBaseObject)e.NewEvent["TargetInstance"];

            String driveName = (string)wmiDevice["DeviceID"];

            string volumeName = wmiDevice.Properties["VolumeName"].Value == null? "" : wmiDevice.Properties["VolumeName"].Value.ToString();

            if (!string.IsNullOrEmpty(driveName))

            {

                if (OnDeviceChanged != null)

                {

                    OnDeviceChanged(null, new DeviceChangedEventArgs()

                    {

                        DriverName = driveName,

                        Action = DeviceChangedAction.Remove

                    });

                }

            }

        }



        public event DeviceChangedEventHandler OnDeviceChanged;

    }

    

//使用方法
watcher = new UsbDriverWatcher();
watcher.OnDeviceChanged += watcher_OnDeviceChanged;
watcher.Start();

 
复制代码

3、 使用WndProc方法来监听外接设备变化的方法:

复制代码
        IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)

        {

             Handle messages...

            if (msg == WM_DEVICECHANGE)

            {



                App.Log.WriteInfo("Device change message received in WndProc.");

                if (!ViewModelLocator.Main._loading)

                {

                    // need to start a new thread to load driver list

                    // http://stackoverflow.com/questions/3921661/disconnectedcontext-mda-when-calling-wmi-functions-in-single-threaded-applicatio

                    System.Threading.Thread t = new System.Threading.Thread(ViewModelLocator.Main.LoadDrivers);

                    t.Start();

                }

            }

           

            return IntPtr.Zero;

        }

你可能感兴趣的:(C#)