【发布时间】:2018-10-01 20:23:32
【问题描述】:
我正在尝试使用 WinForm 桌面 C# 应用程序检测 USB 设备插入和移除:
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;
}
}
}
}
【问题讨论】:
-
pdData.Value可以是:UInt16forEventType,UInt8forSECURITY_DESCRIPTOR和UInt64forTIME_CREATED。这些是e.NewEvent公开的 3 个属性。当然,您不能将其中任何一个投射到ManagementBaseObject。您可以强制转换e.NewEvent,但它已经派生自该基础对象,因此您不会获得它的另一个“视图”。 -
@Jimi 我不确定我是否做对了,你的意思是我必须解析,就像这个
ManagementBaseObject mbo = (ManagementBaseObject)UInt16.Parse(pdData.Value);,但是如果它是字符串的对象。所以我仍然不确定如何获得想要的结果 -
啊,不,对不起。我没有注意到您更改了 WMI 观察程序方法。你的基类现在是
TargetInstance。那是一个完整的ManagementObject。属性名当然是“TargetInstance”,你可以照常解析。它将包含Win32_DiskDrive基本信息。 -
好吧,更明确地说,您可以这样转换:
ManagementBaseObject MOBbase = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;。然后,您有 51 个新属性,它们映射到Win32_DiskDriveMO 类型,具有常用属性“Caption”、“DeviceID”、“Capabilities”等。 -
@Jimi 我已经将它从
ManagementBaseObject mbo = (ManagementBaseObject)pdData.Value;更改为ManagementBaseObject mbo = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;,现在它甚至没有检测到插拔事件
标签: c# winforms exception usb system.management