如何获取最近连接的 USB 设备的信息?

Jer*_*boy 5 .net c# windows wmi systemmanagement

当 USB 设备与Win32_DeviceChangeEvent连接时我可以捕获

但只允许查看 3 个属性

class Win32_DeviceChangeEvent : __ExtrinsicEvent
{
  uint8  SECURITY_DESCRIPTOR[];
  uint64 TIME_CREATED;
  uint16 EventType;
};
Run Code Online (Sandbox Code Playgroud)

但我不明白如何获取有关该设备的所有信息。具体来说,它的端口和集线器、VirtualHubAdress Name等。

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();
}
Run Code Online (Sandbox Code Playgroud)

也许我可以用这样的方法来做到这一点

[DllImport("UseFull.dll")] 
private IntpPtr GetAllinfo(params);
Run Code Online (Sandbox Code Playgroud)

Jim*_*imi 7

Win32_DeviceChangeEvent仅报告发生的事件类型事件时间(uint64,表示 UTC 1601 年 1 月 1 日之后的 100 纳秒间隔)。如果您还想知道什么到达或被删除,那就没什么用了。

\n

我建议改用WqlEventQuery类,将其EventClassName设置为__InstanceOperationEvent
\n此系统类提供了一个TargetInstance可以转换为ManagementBaseObject 的属性,它是完整的管理对象,还提供有关生成事件的设备的基本信息。
\n此信息包括(除了设备的友好名称之外)PNPDeviceID,它可用于构建其他查询以进一步检查引用的设备。

\n

WqlEventQuery\ 的Condition属性可以在此处设置为TargetInstance ISA \'Win32_DiskDrive\'
\n它可以设置为任何其他Win32_感兴趣的类别。

\n

设置事件侦听器(本地计算机):
\n(调用事件处理程序DeviceChangedEvent

\n
var query = new WqlEventQuery() {\n    EventClassName = "__InstanceOperationEvent",\n    WithinInterval = new TimeSpan(0, 0, 3),\n    Condition = @"TargetInstance ISA \'Win32_DiskDrive\'"\n};\n\nvar scope = new ManagementScope("root\\\\CIMV2");\nusing (var moWatcher = new ManagementEventWatcher(scope, query))\n{\n    moWatcher.Options.Timeout = ManagementOptions.InfiniteTimeout;\n    moWatcher.EventArrived += new EventArrivedEventHandler(DeviceChangedEvent);\n    moWatcher.Start();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

事件处理程序在 中接收表示Win32_DiskDrivee.NewEvent.Properties["TargetInstance"]类的管理对象。\n请参阅有关此处直接可用的属性的文档。

\n

__InstanceOperationEvent由 报告的感兴趣的派生类可以e.NewEvent.ClassPath.ClassName是:

\n

__InstanceCreationEvent:已检测到新设备到达。
\n __InstanceDeletionEvent:已检测到设备删除。
\n __InstanceModificationEvent:现有设备已以某种方式修改。

\n

请注意,该事件是在辅助线程中引发的,我们需要BeginInvoke()UI 线程使用新信息更新 UI。
\n\xe2\x96\xb6 您应该避免Invoke()在这里,因为它是同步的:它将阻塞处理程序,直到方法完成。此外,在这种情况下,死锁的可能性并不遥远。

\n

请参阅此处:获取某个类的 USB 存储设备的序列号,该类提供了有关设备的大部分可用信息(信息经过筛选以仅显示 USB 设备,但可以删除筛选器)。

\n
private void DeviceChangedEvent(object sender, EventArrivedEventArgs e)\n{\n    using (var moBase = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)\n    {\n        string oInterfaceType = moBase?.Properties["InterfaceType"]?.Value.ToString();\n        string devicePNPId = moBase?.Properties["PNPDeviceID"]?.Value.ToString();\n        string deviceDescription = moBase?.Properties["Caption"]?.Value.ToString();\n        string eventMessage = $"{oInterfaceType}: {deviceDescription} ";\n\n        switch (e.NewEvent.ClassPath.ClassName)\n        {\n            case "__InstanceDeletionEvent":\n                eventMessage += " removed";\n                break;\n            case "__InstanceCreationEvent":\n                eventMessage += "inserted";\n                break;\n            case "__InstanceModificationEvent":\n            default:\n                eventMessage += $" {e.NewEvent.ClassPath.ClassName}";\n                break;\n        }\n        BeginInvoke(new Action(() => UpdateUI(eventMessage)));\n    }\n}\n\nprivate void UpdateUI(string message)\n{\n   //Update the UI controls with information provided by the event\n}\n
Run Code Online (Sandbox Code Playgroud)\n