本文介绍了捕获USB插拔事件System.InvalidCastException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我正在尝试检测USB设备插入并使用WinForm桌面C#应用程序删除: public Form1() { InitializeComponent(); USB(); } 然后: private void USB() { WqlEventQuery weqQuery = new WqlEventQuery(); weqQuery.EventClassName = __InstanceOperationEvent; weqQuery.WithinInterval = new TimeSpan(0,0,3); weqQuery.Condition = @ TargetInstance ISA‘Win32_DiskDrive’; var m_mewWatcher = new ManagementEventWatcher(weqQuery); m_mewWatcher.EventArrived + =新的EventArrivedEventHandler(m_mewWatcher_EventArrived); m_mewWatcher.Start(); } 和: static void m_mewWatcher_EventArrived(object sender,EventArrivedEventArgs e) { bool bUSBEvent = false; foreach(e.NewEvent.Properties中的PropertyData pdData) { ManagementBaseObject mbo =(ManagementBaseObject)e.NewEvent.Properties [ TargetInstance]。Value; // ManagementBaseObject mbo =(ManagementBaseObject)pdData.Value; if(mbo!= null) { foreach(mbo.Property中的PropertyData pdDataSub) { if(pdDataSub.Name == InterfaceType& & pdDataSub.Value.ToString()== USB) { bUSBEvent = true; 休息时间; } } if(bUSBEvent) { if(e.NewEvent.ClassPath.ClassName == __InstanceCreationEvent) { MessageBox.Show(已插入USB); } else if(e.NewEvent.ClassPath.ClassName == __InstanceDeletionEvent) { MessageBox.Show( USB已插入); } } } } } 但是我发现 ManagementBaseObject mbo =(ManagementBaseObject)pdData.Value; 出现异常,当检测到USB更改时: Controller.exe中发生了'System.InvalidCastException'类型的异常,但未在用户代码中处理 其他信息:无法将类型为'System.UInt64'的对象转换为类型为'System.Management.ManagementBaseObject'。 编辑: 使用系统; 使用System.Windows.Forms; 使用System.Management; 命名空间测试 {公共局部类Form1:表单 {公共Form1() { InitializeComponent() ; } private void button1_Click(对象发送者,EventArgs e) { WqlEventQuery query = new WqlEventQuery() { EventClassName = __InstanceOperationEvent, InternalInterval =新的TimeSpan(0,0,3),条件= @ TargetInstance ISA'Win32_DiskDrive' }; 使用(ManagementEventWatcher MOWatcher = new ManagementEventWatcher(query)) { MOWatcher.EventArrived + = new EventArrivedEventHandler(DeviceInsertedEvent); MOWatcher.Start(); } } 私有无效DeviceInsertedEvent(对象发送者,EventArrivedEventArgs e) {使用(ManagementBaseObject MOBbase =(ManagementBaseObject)e.NewEvent.Properties [ TargetInstance]。Value) { bool DriveArrival = false; string EventMessage = string.Empty; 字符串oInterfaceType = MOBbase.Properties [ InterfaceType] ?. Value.ToString(); if(e.NewEvent.ClassPath.ClassName.Equals( __ InstanceDeletionEvent)) { DriveArrival = false; EventMessage = oInterfaceType +驱动器已移除; } else { DriveArrival = true; EventMessage = oInterfaceType +已插入驱动器; } EventMessage + =: + MOBbase.Properties [ Caption] ?. Value.ToString(); this.BeginInvoke((MethodInvoker)delegate {this.UpdateUI(DriveArrival,EventMessage);}); } } private void UpdateUI(bool IsDriveInserted,string message) { if(IsDriveInserted) { this.label1.Text =消息; } else { this.label1.Text = message; } } } } 解决方案在这里, [DllImport( user32.dll,SetLastError = true,CharSet = CharSet.Auto)] 内部静态外部uint RegisterWindowMessage(string lpString); 私人uint CancelAutoPlay = 0; 私人void button1_Click(对象发送者,EventArgs e) { WqlEventQuery查询=新WqlEventQuery(){ EventClassName = __InstanceOperationEvent, = new TimeSpan(0,0,3),条件= @ TargetInstance ISA'Win32_DiskDrive' }; ManagementScope范围=新的ManagementScope( root\\CIMV2); 使用(ManagementEventWatcher MOWatcher =新的ManagementEventWatcher(查询)) { MOWatcher.Options.Timeout = ManagementOptions.InfiniteTimeout; MOWatcher.EventArrived + =新的EventArrivedEventHandler(DeviceChangedEvent); MOWatcher.Start(); } } 私人无效DeviceChangedEvent(对象发送者,EventArrivedEventArgs e) {使用(ManagementBaseObject MOBbase =(ManagementBaseObject)e.NewEvent.Properties [ TargetInstance]。Value) { bool DriveArrival = false; string EventMessage = string.Empty; 字符串oInterfaceType = MOBbase.Properties [ InterfaceType] ?. Value.ToString(); if(e.NewEvent.ClassPath.ClassName.Equals( __ InstanceDeletionEvent)) { DriveArrival = false; EventMessage = oInterfaceType +驱动器已移除; } else { DriveArrival = true; EventMessage = oInterfaceType +已插入驱动器; } EventMessage + =: + MOBbase.Properties [ Caption] ?. Value.ToString(); this.BeginInvoke((MethodInvoker)delegate {this.UpdateUI(DriveArrival,EventMessage);}); } } private void UpdateUI(bool IsDriveInserted,string message) { if(IsDriveInserted) this .lblDeviceArrived.Text =消息; else this.lblDeviceRemoved.Text = message; } [SecurityPermission(SecurityAction.Demand,Flags = SecurityPermissionFlag.UnmanagedCode)] 受保护的覆盖无效WndProc(ref Message m) { base.WndProc(ref m); if(CancelAutoPlay == 0) CancelAutoPlay = RegisterWindowMessage( QueryCancelAutoPlay); if((int)m.Msg == CancelAutoPlay){m.Result =(IntPtr)1; } } I'm trying to detect USB device insertion and remove with WinForm desktop C# application: public Form1() { InitializeComponent(); USB(); }then: private void USB(){ WqlEventQuery weqQuery = new WqlEventQuery(); weqQuery.EventClassName = "__InstanceOperationEvent"; weqQuery.WithinInterval = new TimeSpan(0, 0, 3); weqQuery.Condition = @"TargetInstance ISA 'Win32_DiskDrive'"; var m_mewWatcher = new ManagementEventWatcher(weqQuery); m_mewWatcher.EventArrived += new EventArrivedEventHandler(m_mewWatcher_EventArrived); m_mewWatcher.Start();}and:static void m_mewWatcher_EventArrived(object sender, EventArrivedEventArgs e) { bool bUSBEvent = false; foreach (PropertyData pdData in e.NewEvent.Properties) { ManagementBaseObject mbo = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value; // ManagementBaseObject mbo = (ManagementBaseObject)pdData.Value; if (mbo != null) { foreach (PropertyData pdDataSub in mbo.Properties) { if (pdDataSub.Name == "InterfaceType" && pdDataSub.Value.ToString() == "USB") { bUSBEvent = true; break; } } if (bUSBEvent) { if (e.NewEvent.ClassPath.ClassName == "__InstanceCreationEvent") { MessageBox.Show ("USB was plugged in"); } else if (e.NewEvent.ClassPath.ClassName == "__InstanceDeletionEvent") { MessageBox.Show("USB was plugged out"); } } } } }But I got exception with ManagementBaseObject mbo = (ManagementBaseObject)pdData.Value; when detects USB change: An exception of type 'System.InvalidCastException' occurred in Controller.exe but was not handled in user code Additional information: Unable to cast object of type 'System.UInt64' to type 'System.Management.ManagementBaseObject'.edit:using System;using System.Windows.Forms;using System.Management;namespace test{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { WqlEventQuery query = new WqlEventQuery() { EventClassName = "__InstanceOperationEvent", WithinInterval = new TimeSpan(0, 0, 3), Condition = @"TargetInstance ISA 'Win32_DiskDrive'" }; using (ManagementEventWatcher MOWatcher = new ManagementEventWatcher(query)) { MOWatcher.EventArrived += new EventArrivedEventHandler(DeviceInsertedEvent); MOWatcher.Start(); } } private void DeviceInsertedEvent(object sender, EventArrivedEventArgs e) { using (ManagementBaseObject MOBbase = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value) { bool DriveArrival = false; string EventMessage = string.Empty; string oInterfaceType = MOBbase.Properties["InterfaceType"]?.Value.ToString(); if (e.NewEvent.ClassPath.ClassName.Equals("__InstanceDeletionEvent")) { DriveArrival = false; EventMessage = oInterfaceType + " Drive removed"; } else { DriveArrival = true; EventMessage = oInterfaceType + " Drive inserted"; } EventMessage += ": " + MOBbase.Properties["Caption"]?.Value.ToString(); this.BeginInvoke((MethodInvoker)delegate { this.UpdateUI(DriveArrival, EventMessage); }); } } private void UpdateUI(bool IsDriveInserted, string message) { if (IsDriveInserted) { this.label1.Text = message; } else { this.label1.Text = message; } } }} 解决方案 Here, the ManagementEventWatcher is initialized on a Button.Click() event. Of course, you can initialize it elsewhere. In Form.Load() for example.The ManagementEventWatcher.EventArrived event is subscribed, setting the delegate to private void DeviceInsertedEvent(). The watching procedure is the started using ManagementEventWatcher.Start() (MOWatcher.Start();)When an event is notified, the EventArrivedEventArgs e.NewEvent.Properties["TargetInstance"].Value will be set to a ManagementBaseObject, which will reference a Win32_DiskDrive WMI/CIM class.Read the documentation to see what informations are available in this class.This event is not rasised in the UI Thread. To notify the main UI interface of the nature of the event, we need to .Invoke() a method in that thread.this.BeginInvoke((MethodInvoker)delegate { this.UpdateUI(DriveArrival, EventMessage); });Here, the private void UpdateUI() method is called, delegating the UI update to a method which is executed in the UI thread.Update:Added RegisterWindowMessage() to register QueryCancelAutoPlay, to prevent the AutoPlay window from popping up in front of our Form, stealing the focus.A visual sample of the results:[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]internal static extern uint RegisterWindowMessage(string lpString);private uint CancelAutoPlay = 0;private void button1_Click(object sender, EventArgs e){ WqlEventQuery query = new WqlEventQuery() { EventClassName = "__InstanceOperationEvent", WithinInterval = new TimeSpan(0, 0, 3), Condition = @"TargetInstance ISA 'Win32_DiskDrive'" }; ManagementScope scope = new ManagementScope("root\\CIMV2"); using (ManagementEventWatcher MOWatcher = new ManagementEventWatcher(query)) { MOWatcher.Options.Timeout = ManagementOptions.InfiniteTimeout; MOWatcher.EventArrived += new EventArrivedEventHandler(DeviceChangedEvent); MOWatcher.Start(); }}private void DeviceChangedEvent(object sender, EventArrivedEventArgs e){ using (ManagementBaseObject MOBbase = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value) { bool DriveArrival = false; string EventMessage = string.Empty; string oInterfaceType = MOBbase.Properties["InterfaceType"]?.Value.ToString(); if (e.NewEvent.ClassPath.ClassName.Equals("__InstanceDeletionEvent")) { DriveArrival = false; EventMessage = oInterfaceType + " Drive removed"; } else { DriveArrival = true; EventMessage = oInterfaceType + " Drive inserted"; } EventMessage += ": " + MOBbase.Properties["Caption"]?.Value.ToString(); this.BeginInvoke((MethodInvoker)delegate { this.UpdateUI(DriveArrival, EventMessage); }); }}private void UpdateUI(bool IsDriveInserted, string message){ if (IsDriveInserted) this.lblDeviceArrived.Text = message; else this.lblDeviceRemoved.Text = message;}[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]protected override void WndProc(ref Message m){ base.WndProc(ref m); if (CancelAutoPlay == 0) CancelAutoPlay = RegisterWindowMessage("QueryCancelAutoPlay"); if ((int)m.Msg == CancelAutoPlay) { m.Result = (IntPtr)1; }} 这篇关于捕获USB插拔事件System.InvalidCastException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-29 22:21