c# 获取移动硬盘信息监听移动设备的弹出与插入事件
Posted lonelyxmas
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c# 获取移动硬盘信息监听移动设备的弹出与插入事件相关的知识,希望对你有一定的参考价值。
原文: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;
以上是关于c# 获取移动硬盘信息监听移动设备的弹出与插入事件的主要内容,如果未能解决你的问题,请参考以下文章