我正在尝试检测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 += new EventArrivedEventHandler(m_mewWatcher_EventArrived);
m_mewWatcher.Start();
}
和:
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");
}
}
}
}
}
但是当检测到USB变化时,我遇到了ManagementBaseObject mbo = (ManagementBaseObject)pdData.Value;
的异常情况:
“ System.InvalidCastException”类型的异常发生在 Controller.exe,但未在用户代码中处理
其他信息:无法转换类型为'System.UInt64'的对象 键入“ System.Management.ManagementBaseObject”。
编辑:
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;
}
}
}
}
答案 0 :(得分:0)
此处,ManagementEventWatcher在Button.Click()
事件中被初始化。当然,您可以在其他地方初始化它。例如在Form.Load()
中。
已预订ManagementEventWatcher.EventArrived事件,将委托设置为private void DeviceInsertedEvent()
。观看过程是使用ManagementEventWatcher.Start()(MOWatcher.Start();
)开始的
通知事件后,EventArrivedEventArgs e.NewEvent。Properties["TargetInstance"].Value
将被设置为ManagementBaseObject,它将引用Win32_DiskDrive WMI / CIM类。
阅读文档以了解此类中的可用信息。
UI线程中未引发此事件。要通知主UI界面事件的性质,我们需要在该线程中.invoke()一个方法。
this.BeginInvoke((MethodInvoker)delegate { this.UpdateUI(DriveArrival, EventMessage); });
在这里,调用private void UpdateUI()
方法,将UI更新委托给在UI线程中执行的方法。
更新:
添加了RegisterWindowMessage()来注册QueryCancelAutoPlay,以防止“自动播放”窗口在我们的窗体前弹出,从而夺取焦点。
结果的直观示例:
[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; }
}