How do i get info about recently connected usb device

别等时光非礼了梦想. 提交于 2020-01-20 07:04:04

问题


I can catch when usb device is connected with Win32_DeviceChangeEvent

but there are only 3 properties allowed to view

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

But i don't understand how to get all info about this device. Specifically, its port and hub, VirtualHubAdress Name and etc.

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();
}

maybe i can do it with using smth like this

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

回答1:


The Win32_DeviceChangeEvent reports just the type of event that occurred and the Time of the event (uint64, representing 100-nanosecond intervals after January 1, 1601, UTC). No that much useful if you also want to know what arrived or was removed.

I suggest to use instead the WqlEventQuery class, setting its EventClassName to __InstanceOperationEvent.
This system class provides a TargetInstance property the can be cast to a ManagementBaseObject, the full management object that also provides base information on the Device that generated the event.
Among these information (which include the friendly name of the Device), the PNPDeviceID, which can be used to build other queries to further inspect the Device referenced.

The WqlEventQuery's Condition property can be set here to TargetInstance ISA 'Win32_DiskDrive'.
It can be set to any other Win32_ class of interest.

Setup the event listener (local machine):
(The event handler is called DeviceChangedEvent)

WqlEventQuery query = new WqlEventQuery() {
    EventClassName = "__InstanceOperationEvent",
    WithinInterval = new TimeSpan(0, 0, 3),
    Condition = @"TargetInstance ISA 'Win32_DiskDrive'"
};

ManagementScope scope = new ManagementScope("root\\CIMV2");
using (ManagementEventWatcher moWatcher = new ManagementEventWatcher(scope, query))
{
    moWatcher.Options.Timeout = ManagementOptions.InfiniteTimeout;
    moWatcher.EventArrived += new EventArrivedEventHandler(DeviceChangedEvent);
    moWatcher.Start();
}

The event handler receives, in e.NewEvent.Properties["TargetInstance"], the Management Object representing a Win32_DiskDrive class.
See the Docs about the properties directly available here.

The __InstanceOperationEvent derived classes of interest, reported by the e.NewEvent.ClassPath.ClassName, can be:

__InstanceCreationEvent: A new Device arrival has been detected.
__InstanceDeletionEvent: A Device removal has been detected.
__InstanceModificationEvent: An existing device has been modified in some way.

Note that the event is raised in a secondary thread, we need to BeginInvoke the UI thread to update the UI with the new informations.

See here: Get serial number of usb storage device for a class that provides most of the information available about a device (the informations are filtered to show USB devices only, but the filter can be removed).

private void DeviceChangedEvent(object sender, EventArrivedEventArgs e)
{
    using (ManagementBaseObject 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";
                this.BeginInvoke(new MethodInvoker(() => { this.UpdateUI(eventMessage); }));
                break;
            case "__InstanceCreationEvent":
                eventMessage += "inserted";
                this.BeginInvoke(new MethodInvoker(() => { this.UpdateUI(eventMessage); }));
                break;
            case "__InstanceModificationEvent":
            default:
                Console.WriteLine(e.NewEvent.ClassPath.ClassName);
                break;
        }
    }
}


private void UpdateUI(string message)
{
   //Update the UI controls with the updated informations
}



回答2:


You can try to use Win32_PnPEntity to get details. Win32_PnPEntity class




回答3:


You can use ORMi to create a watcher so you can get information about any new device:

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;

And then you can watch for the events:

private static void Watcher_WMIEventArrived(object sender, WMIEventArgs e)
{
    //DO YOUR WORK
}


来源:https://stackoverflow.com/questions/54294441/how-do-i-get-info-about-recently-connected-usb-device

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!