如何获取有关最近连接的 USB 设备的信息?
How do I get information about recently connected USB device?
当usb设备连接到Win32_DeviceChangeEvent
时我可以捕捉到
但只有 3 个属性允许查看
class Win32_DeviceChangeEvent : __ExtrinsicEvent
{
uint8 SECURITY_DESCRIPTOR[];
uint64 TIME_CREATED;
uint16 EventType;
};
但我不明白如何获取关于此设备的所有信息。具体来说,它的端口和集线器、VirtualHubAdress 名称 等等
public enum EventType
{
Inserted = 2,
Removed = 3
}
public static void RegisterUsbDeviceNotification()
{
var watcher = new ManagementEventWatcher();
var query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2");
//watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
watcher.EventArrived += (s, e) =>
{
//here is im need to get info about this device
EventType eventType = (EventType)(Convert.ToInt16(e.NewEvent.Properties["EventType"].Value));
};
watcher.Query = query;
watcher.Start();
}
也许我可以像这样使用smth
[DllImport("UseFull.dll")]
private IntpPtr GetAllinfo(params);
您可以尝试使用Win32_PnPEntity获取详细信息。 Win32_PnPEntity class
您可以使用 ORMi 创建观察器,以便获取有关任何新设备的信息:
WMIHelper helper = new WMIHelper("root\CimV2");
WMIWatcher watcher = new WMIWatcher("root\CimV2", "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PnPEntity'");
watcher.WMIEventArrived += Watcher_WMIEventArrived;
然后您可以观看事件:
private static void Watcher_WMIEventArrived(object sender, WMIEventArgs e)
{
//DO YOUR WORK
}
Win32_DeviceChangeEvent 仅报告发生的事件类型和事件时间(uint64,表示 1601 年 1 月 1 日之后的 100 纳秒间隔,UTC)。如果您还想知道什么到达或被移除,就没那么有用了。
我建议改用 WqlEventQuery class, setting its EventClassName to __InstanceOperationEvent。
本系统class提供了TargetInstance
属性可以转换为ManagementBaseObject的完整管理对象,也提供了基础信息在生成事件的设备上。
在这些信息(包括设备的友好名称)中,PNPDeviceID
可用于构建其他查询以进一步检查引用的设备。
WqlEventQuery
的Condition属性这里可以设置为TargetInstance ISA 'Win32_DiskDrive'
.
它可以设置为任何其他 Win32_
class 感兴趣。
设置事件侦听器(本地计算机):
(事件处理程序调用DeviceChangedEvent
)
var query = new WqlEventQuery() {
EventClassName = "__InstanceOperationEvent",
WithinInterval = new TimeSpan(0, 0, 3),
Condition = @"TargetInstance ISA 'Win32_DiskDrive'"
};
var scope = new ManagementScope("root\CIMV2");
using (var moWatcher = new ManagementEventWatcher(scope, query))
{
moWatcher.Options.Timeout = ManagementOptions.InfiniteTimeout;
moWatcher.EventArrived += new EventArrivedEventHandler(DeviceChangedEvent);
moWatcher.Start();
}
事件处理程序在 e.NewEvent.Properties["TargetInstance"]
中接收表示 Win32_DiskDrive class.
的管理对象
请参阅此处直接提供的有关属性的文档。
由 e.NewEvent.ClassPath.ClassName
报告的感兴趣的 __InstanceOperationEvent
衍生 classes 可以是:
__InstanceCreationEvent: 检测到新设备到达。
__InstanceDeletionEvent: 检测到设备移除。
__InstanceModificationEvent: 对现有设备进行了某种方式的修改。
请注意,事件是在辅助线程中引发的,我们需要 BeginInvoke()
UI 线程用新信息更新 UI。
▶ 你应该避免在这里使用 Invoke()
,因为它是同步的:它会阻塞处理程序直到方法完成。此外,在这种情况下,死锁并不是完全不可能的。
请参阅此处: class,它提供了有关设备的大部分可用信息(信息经过过滤以仅显示 USB 设备,但可以删除过滤器)。
private void DeviceChangedEvent(object sender, EventArrivedEventArgs e)
{
using (var moBase = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)
{
string oInterfaceType = moBase?.Properties["InterfaceType"]?.Value.ToString();
string devicePNPId = moBase?.Properties["PNPDeviceID"]?.Value.ToString();
string deviceDescription = moBase?.Properties["Caption"]?.Value.ToString();
string eventMessage = $"{oInterfaceType}: {deviceDescription} ";
switch (e.NewEvent.ClassPath.ClassName)
{
case "__InstanceDeletionEvent":
eventMessage += " removed";
BeginInvoke(new Action(() => UpdateUI(eventMessage)));
break;
case "__InstanceCreationEvent":
eventMessage += "inserted";
BeginInvoke(new Action(() => UpdateUI(eventMessage)));
break;
case "__InstanceModificationEvent":
default:
Console.WriteLine(e.NewEvent.ClassPath.ClassName);
break;
}
}
}
private void UpdateUI(string message)
{
//Update the UI controls with information provided by the event
}
当usb设备连接到Win32_DeviceChangeEvent
时我可以捕捉到但只有 3 个属性允许查看
class Win32_DeviceChangeEvent : __ExtrinsicEvent
{
uint8 SECURITY_DESCRIPTOR[];
uint64 TIME_CREATED;
uint16 EventType;
};
但我不明白如何获取关于此设备的所有信息。具体来说,它的端口和集线器、VirtualHubAdress 名称 等等
public enum EventType
{
Inserted = 2,
Removed = 3
}
public static void RegisterUsbDeviceNotification()
{
var watcher = new ManagementEventWatcher();
var query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2");
//watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
watcher.EventArrived += (s, e) =>
{
//here is im need to get info about this device
EventType eventType = (EventType)(Convert.ToInt16(e.NewEvent.Properties["EventType"].Value));
};
watcher.Query = query;
watcher.Start();
}
也许我可以像这样使用smth
[DllImport("UseFull.dll")]
private IntpPtr GetAllinfo(params);
您可以尝试使用Win32_PnPEntity获取详细信息。 Win32_PnPEntity class
您可以使用 ORMi 创建观察器,以便获取有关任何新设备的信息:
WMIHelper helper = new WMIHelper("root\CimV2");
WMIWatcher watcher = new WMIWatcher("root\CimV2", "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PnPEntity'");
watcher.WMIEventArrived += Watcher_WMIEventArrived;
然后您可以观看事件:
private static void Watcher_WMIEventArrived(object sender, WMIEventArgs e)
{
//DO YOUR WORK
}
Win32_DeviceChangeEvent 仅报告发生的事件类型和事件时间(uint64,表示 1601 年 1 月 1 日之后的 100 纳秒间隔,UTC)。如果您还想知道什么到达或被移除,就没那么有用了。
我建议改用 WqlEventQuery class, setting its EventClassName to __InstanceOperationEvent。
本系统class提供了TargetInstance
属性可以转换为ManagementBaseObject的完整管理对象,也提供了基础信息在生成事件的设备上。
在这些信息(包括设备的友好名称)中,PNPDeviceID
可用于构建其他查询以进一步检查引用的设备。
WqlEventQuery
的Condition属性这里可以设置为TargetInstance ISA 'Win32_DiskDrive'
.
它可以设置为任何其他 Win32_
class 感兴趣。
设置事件侦听器(本地计算机):
(事件处理程序调用DeviceChangedEvent
)
var query = new WqlEventQuery() {
EventClassName = "__InstanceOperationEvent",
WithinInterval = new TimeSpan(0, 0, 3),
Condition = @"TargetInstance ISA 'Win32_DiskDrive'"
};
var scope = new ManagementScope("root\CIMV2");
using (var moWatcher = new ManagementEventWatcher(scope, query))
{
moWatcher.Options.Timeout = ManagementOptions.InfiniteTimeout;
moWatcher.EventArrived += new EventArrivedEventHandler(DeviceChangedEvent);
moWatcher.Start();
}
事件处理程序在 e.NewEvent.Properties["TargetInstance"]
中接收表示 Win32_DiskDrive class.
的管理对象
请参阅此处直接提供的有关属性的文档。
由 e.NewEvent.ClassPath.ClassName
报告的感兴趣的 __InstanceOperationEvent
衍生 classes 可以是:
__InstanceCreationEvent: 检测到新设备到达。
__InstanceDeletionEvent: 检测到设备移除。
__InstanceModificationEvent: 对现有设备进行了某种方式的修改。
请注意,事件是在辅助线程中引发的,我们需要 BeginInvoke()
UI 线程用新信息更新 UI。
▶ 你应该避免在这里使用 Invoke()
,因为它是同步的:它会阻塞处理程序直到方法完成。此外,在这种情况下,死锁并不是完全不可能的。
请参阅此处:
private void DeviceChangedEvent(object sender, EventArrivedEventArgs e)
{
using (var moBase = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)
{
string oInterfaceType = moBase?.Properties["InterfaceType"]?.Value.ToString();
string devicePNPId = moBase?.Properties["PNPDeviceID"]?.Value.ToString();
string deviceDescription = moBase?.Properties["Caption"]?.Value.ToString();
string eventMessage = $"{oInterfaceType}: {deviceDescription} ";
switch (e.NewEvent.ClassPath.ClassName)
{
case "__InstanceDeletionEvent":
eventMessage += " removed";
BeginInvoke(new Action(() => UpdateUI(eventMessage)));
break;
case "__InstanceCreationEvent":
eventMessage += "inserted";
BeginInvoke(new Action(() => UpdateUI(eventMessage)));
break;
case "__InstanceModificationEvent":
default:
Console.WriteLine(e.NewEvent.ClassPath.ClassName);
break;
}
}
}
private void UpdateUI(string message)
{
//Update the UI controls with information provided by the event
}