无法使用 WMI 在 .NET Framework 中实现 USB 检测 API
Cannot implement USB Detection in .NET Framework using WMI API
- 我正在尝试实现以下 link 中的代码:Detecting USB drive insertion and removal using windows service and c#
- 我认为我遇到的问题是当插入或移除设备时,后台线程没有通知我的主 UI 线程。我通过无法更新用户控件中标签的内容验证了这一点。
- 我在下面包含了我的源代码:
private void DeviceInsertedEvent(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
foreach (var property in instance.Properties)
{
MessageBox.Show(property.Name + " = " + property.Value); // Dialog box appears as expected.
StatusMessage.Content = $"{property.Name} = {property.Value}";
}
StatusMessage.Content = "Removable Drive detected!"; //label content should be updated here, and for some reason it is not.
bool isDriveRemoved = FindRemovableDrive(); //get the drive info
if (isDriveRemoved || Count > 0)
{
Count = 0;
}
else
{
Count++;
}
}
private void DeviceRemovedEvent(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
foreach (var property in instance.Properties)
{
MessageBox.Show(property.Name + " = " + property.Value); // Dialog box appears as expected, but label is not updated.
}
StatusMessage.Content = $"{property.Name} = {property.Value}";
FileMenu.Items.Clear(); // the file menu should be getting cleared here.
}
private void backgroundWorker1_DoWork(object sender, RoutedEventArgs e)
{
WqlEventQuery insertQuery = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'");
ManagementEventWatcher insertWatcher = new ManagementEventWatcher(insertQuery);
insertWatcher.EventArrived += DeviceInsertedEvent;
insertWatcher.Start();
WqlEventQuery removeQuery = new WqlEventQuery("SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'");
ManagementEventWatcher removeWatcher = new ManagementEventWatcher(removeQuery);
removeWatcher.EventArrived += DeviceRemovedEvent;
removeWatcher.Start();
// Do something while waiting for events
//Thread.Sleep(10000);
}
-任何 input/solutions 将不胜感激。
感谢您的宝贵时间,
迈克尔
您可以使用 WMI 事件在硬件发生变化时收到通知,而不是定期扫描设备。
为即插即用事件启动侦听器:
var wmiPath = new ManagementPath(@"root\cimv2");
var scope = new ManagementScope(wmiPath);
scope.Connect();
var instanceQuery = new WqlEventQuery("__InstanceOperationEvent",
new TimeSpan(0, 0, 1),
"TargetInstance isa \"Win32_PnPEntity\"");
wmiWatcher = new ManagementEventWatcher(scope, instanceQuery);
wmiWatcher.EventArrived += OnInstanceEvent;
wmiWatcher.Start();
事件处理程序:
private void OnInstanceEvent(object sender, EventArrivedEventArgs ea) {
var eventType = (string)ea.NewEvent["__CLASS"];
var targetWmiObj = ea.NewEvent["TargetInstance"] as ManagementBaseObject;
var deviceId = (string)targetWmiObj["deviceId"];
if (String.Equals("__InstanceCreationEvent", (string)ea.NewEvent["__CLASS"], StringComparison.Ordinal)) {
if (/* Filter on the device id for what is interesting here*/) {
// Handle relevant device arriving
}
}
}
其他事件类型(包括设备移除)还有其他值 NewEvent["__CLASS"]
。
PS。这是来自 WinForms 应用程序的(部分)代码,该应用程序监视插入的专用设备,然后 downloaded/uploaded 来自它的数据。所有工作都在线程池中完成:这里的一切都应该在 WPF 下工作。
- 我正在尝试实现以下 link 中的代码:Detecting USB drive insertion and removal using windows service and c#
- 我认为我遇到的问题是当插入或移除设备时,后台线程没有通知我的主 UI 线程。我通过无法更新用户控件中标签的内容验证了这一点。
- 我在下面包含了我的源代码:
private void DeviceInsertedEvent(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
foreach (var property in instance.Properties)
{
MessageBox.Show(property.Name + " = " + property.Value); // Dialog box appears as expected.
StatusMessage.Content = $"{property.Name} = {property.Value}";
}
StatusMessage.Content = "Removable Drive detected!"; //label content should be updated here, and for some reason it is not.
bool isDriveRemoved = FindRemovableDrive(); //get the drive info
if (isDriveRemoved || Count > 0)
{
Count = 0;
}
else
{
Count++;
}
}
private void DeviceRemovedEvent(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
foreach (var property in instance.Properties)
{
MessageBox.Show(property.Name + " = " + property.Value); // Dialog box appears as expected, but label is not updated.
}
StatusMessage.Content = $"{property.Name} = {property.Value}";
FileMenu.Items.Clear(); // the file menu should be getting cleared here.
}
private void backgroundWorker1_DoWork(object sender, RoutedEventArgs e)
{
WqlEventQuery insertQuery = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'");
ManagementEventWatcher insertWatcher = new ManagementEventWatcher(insertQuery);
insertWatcher.EventArrived += DeviceInsertedEvent;
insertWatcher.Start();
WqlEventQuery removeQuery = new WqlEventQuery("SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'");
ManagementEventWatcher removeWatcher = new ManagementEventWatcher(removeQuery);
removeWatcher.EventArrived += DeviceRemovedEvent;
removeWatcher.Start();
// Do something while waiting for events
//Thread.Sleep(10000);
}
-任何 input/solutions 将不胜感激。
感谢您的宝贵时间,
迈克尔
您可以使用 WMI 事件在硬件发生变化时收到通知,而不是定期扫描设备。
为即插即用事件启动侦听器:
var wmiPath = new ManagementPath(@"root\cimv2");
var scope = new ManagementScope(wmiPath);
scope.Connect();
var instanceQuery = new WqlEventQuery("__InstanceOperationEvent",
new TimeSpan(0, 0, 1),
"TargetInstance isa \"Win32_PnPEntity\"");
wmiWatcher = new ManagementEventWatcher(scope, instanceQuery);
wmiWatcher.EventArrived += OnInstanceEvent;
wmiWatcher.Start();
事件处理程序:
private void OnInstanceEvent(object sender, EventArrivedEventArgs ea) {
var eventType = (string)ea.NewEvent["__CLASS"];
var targetWmiObj = ea.NewEvent["TargetInstance"] as ManagementBaseObject;
var deviceId = (string)targetWmiObj["deviceId"];
if (String.Equals("__InstanceCreationEvent", (string)ea.NewEvent["__CLASS"], StringComparison.Ordinal)) {
if (/* Filter on the device id for what is interesting here*/) {
// Handle relevant device arriving
}
}
}
其他事件类型(包括设备移除)还有其他值 NewEvent["__CLASS"]
。
PS。这是来自 WinForms 应用程序的(部分)代码,该应用程序监视插入的专用设备,然后 downloaded/uploaded 来自它的数据。所有工作都在线程池中完成:这里的一切都应该在 WPF 下工作。