4

当 USB 设备与 Win32_DeviceChangeEvent连接时,我可以捕捉到

但只允许查看 3 个属性

class Win32_DeviceChangeEvent : __ExtrinsicEvent
{
  uint8  SECURITY_DESCRIPTOR[];
  uint64 TIME_CREATED;
  uint16 EventType;
};

但我不明白如何获取有关此设备的所有信息。具体来说,它的端口和集线器,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();
}

也许我可以像这样使用 smth

[DllImport("UseFull.dll")] 
private IntpPtr GetAllinfo(params);
4

3 回答 3

5

Win32_DeviceChangeEvent报告发生的事件类型和事件时间(uint64,表示 1601 年 1 月 1 日之后的 100 纳秒间隔,UTC)。如果您还想知道到达或删除的内容,则没有多大用处。

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

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

设置事件监听器(本地机器):(
调用事件处理程序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类的管理对象。
请参阅有关此处直接可用的属性的文档。

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

__InstanceCreationEvent:检测到新设备到达。
__InstanceDeletionEvent:检测到设备移除。
__InstanceModificationEvent:现有设备已以某种方式进行了修改。

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

请参阅此处:获取 USB 存储设备的序列号,该类提供有关设备的大部分可用信息(信息被过滤以仅显示 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
}
于 2019-01-21T21:57:21.700 回答
0

您可以尝试使用 Win32_PnPEntity 来获取详细信息。Win32_PnPEntity 类

于 2019-01-21T16:56:10.583 回答
0

你可以使用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
}
于 2019-01-21T20:00:43.603 回答