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


    备忘一下改功能,主要通过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;
            }
  • 相关阅读:
    StringTable
    TCP网络协议
    也说JVM内存区域
    JVM类加载
    java中的引用:强、软、弱、虚
    AQS
    vscode支持unicode编码
    设计模式简记-快速改善代码质量的编程规范
    擅事利器
    设计模式简记-通过重构增强代码可测试性实战
  • 原文地址:https://www.cnblogs.com/coolkiss/p/3328825.html
Copyright © 2020-2023  润新知