c# - 无法使用 WMI API 在 .NET Framework 中实现 USB 检测
问题描述
- 我正在尝试从以下链接实现代码:Detecting USB drive injection 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);
}
- 任何输入/解决方案将不胜感激。
谢谢你的时间,
迈克尔
解决方案
您可以使用 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 应用程序的(部分)代码,该应用程序监视正在插入的专用设备,然后从中下载/上传数据。所有工作都在线程池中完成:这里的一切都应该在 WPF 下工作。
推荐阅读
- react-native - React Native上隐藏选项卡时如何让视图绘制空白部分?
- php - 未捕获的错误:在目录中找不到类
- python - 在 django 查询集过滤器中,如何检查 json 字段中的至少一个键是否具有非空值?
- java - Vertx JDBC 如何在后台工作
- linux - linux内核中函数tcp_recvmsg的返回值和msg参数有什么关系?
- reactjs - 为什么选择 ant.design
组件在setState时取消上传请求? - java - rJava 出现意外的 java.awt.HeadlessException
- node.js - 签署 API 密钥 (bittrex api) [节点]
- html - css在列之间添加间距
- android - Navigation Drawer 图标未显示,并且 OnNavigationItemSelectedListener 在单击时不起作用