我是靠谱客的博主 复杂灯泡,最近开发中收集的这篇文章主要介绍WinFrom、C# 学习记录二 监听usb设备变化、获取usb设备信息,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

监听USB设备的插入和弹出

Detecting Media Insertion or Removal,Detecting Media Insertion or Removal - Win32 apps | Microsoft Docs

设备管理消息,WM_DEVICECHANGE 消息 (Winuser.h) - Win32 apps | Microsoft Docs

protected override void WndProc(ref Message sysm)
{
    const int WM_DEVICECHANGE = 0x219;
    const int DBT_DEVICEARRIVAL = 0x8000;
    const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
    const int DBT_DEVNODES_CHANGED = 0x0007;

            try
    {
        if (sysm.Msg == WM_DEVICECHANGE)
        {
            if (sysm.WParam.ToInt32() == DBT_DEVICEARRIVAL)
            {
                //这里

            }
            if (DBT_DEVICEARRIVAL == sysm.WParam.ToInt32())
            {
                //USB设备插入
            }
            else if (DBT_DEVICEREMOVECOMPLETE == sysm.WParam.ToInt32())
            {
                //USB设备拔出
            }
            else if (DBT_DEVNODES_CHANGED == sysm.WParam.ToInt32())
            {
                //USB设备改变
            }
        }
    }
    catch
    { }
    base.WndProc(ref sysm);
}

查询所有USB设备

List<PnPEntityInfo> UsbDevices = new List<PnPEntityInfo>();

// 获取USB控制器及其相关联的设备实体
ManagementObjectCollection USBControllerDeviceCollection = new ManagementObjectSearcher("SELECT * FROM Win32_USBControllerDevice").Get();
if (USBControllerDeviceCollection != null)
{
    foreach (ManagementObject USBControllerDevice in USBControllerDeviceCollection)
    {   // 获取设备实体的DeviceID
        String Dependent = (USBControllerDevice["Dependent"] as String).Split(new Char[] { '=' })[1];

        // 过滤掉没有VID和PID的USB设备
        Match match = Regex.Match(Dependent, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
        if (match.Success)
        {
            UInt16 theVendorID = Convert.ToUInt16(match.Value.Substring(4, 4), 16);   // 供应商标识
            if (VendorID != UInt16.MinValue && VendorID != theVendorID) continue;

            UInt16 theProductID = Convert.ToUInt16(match.Value.Substring(13, 4), 16); // 产品编号
            if (ProductID != UInt16.MinValue && ProductID != theProductID) continue;

            ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE DeviceID=" + Dependent).Get();
            if (PnPEntityCollection != null)
            {
                foreach (ManagementObject Entity in PnPEntityCollection)
                {
                    Guid theClassGuid = new Guid(Entity["ClassGuid"] as String);    // 设备安装类GUID
                    if (ClassGuid != Guid.Empty && ClassGuid != theClassGuid) continue;

                    PnPEntityInfo Element;
                    Element.PNPDeviceID = Entity["PNPDeviceID"] as String;  // 设备ID
                    Element.Name = Entity["Name"] as String;                // 设备名称
                    Element.Description = Entity["Description"] as String;  // 设备描述
                    Element.Service = Entity["Service"] as String;          // 服务
                    Element.Status = Entity["Status"] as String;            // 设备状态
                    Element.VendorID = theVendorID;     // 供应商标识
                    Element.ProductID = theProductID;   // 产品编号
                    Element.ClassGuid = theClassGuid;   // 设备安装类GUID

                    UsbDevices.Add(Element);
                }
            }
        }
    }
}

if (UsbDevices.Count == 0) return null; else return UsbDevices.ToArray();

USB 设备的PID-Product ID,VID-Vendor ID

根据USB规范的规定,所有的USB设备都有供应商ID(VID)和产品识别码(PID),主机通过不同的VID和PID来区别不同的设备,VID和PID都是两个字节长,其中,供应商ID(VID)由供应商向USB执行论坛申请,每个供应商的 VID是唯一的,PID由供应商自行决定,理论上来说,不同的产品、相同产品的不同型号、相同型号的不同设计的产品最好采用不同的PID,以便区别相同厂家的不同设备。

VID和PID通常情况下有两种存储方式,第一种是主控生产商的VID和PID,存储在主控的bootcode中;第二种是设备生产商的VID和PID,该VID和PID存储在主控外部的非易失性存储设备中(EEPROM或Flash)的设备固件中,当USB设备连接主机时,如果固件中有设备生产商的VID和PID,会将该VID和PID报告给主机,而忽略主控生产商的VID和PID。所以理论上一个USB存储设备的VID应该是设备生产商的VID,而不是主控生产商的VID,这两个VID应该是不同的(主控生产商自己生产的设备除外)。

由于VID和PID重复并不会对产品的使用带来严重影响,很多USB设备生产商(山寨厂居多)为了方便,并不会向USB执行论坛申请自己的VID,而是依然沿用主控生产商的VID或随便向产品写入VID和PID;同时,正规厂家只需要申请VID,PID由厂家自行确定,所以存在相同型号的产品,可能采用了不同的主控(商业需要,很正常),而他们的PID是一样的,基于上述原因通过VID和PID就不能准确识别USB设备的主控型号,这个问题大家在使用USB设备的过程中需要注意。

设备类型与GUID

ClassGUIDDevice Description
CDROM4D36E965-E325-11CE-BFC1-08002BE10318CD/DVD/Blu-ray drives
DiskDrive4D36E967-E325-11CE-BFC1-08002BE10318Hard drives
Display4D36E968-E325-11CE-BFC1-08002BE10318Video adapters
FDC4D36E969-E325-11CE-BFC1-08002BE10318Floppy controllers
FloppyDisk4D36E980-E325-11CE-BFC1-08002BE10318Floppy drives
HDC4D36E96A-E325-11CE-BFC1-08002BE10318Hard drive controllers
HIDClass745A17A0-74D3-11D0-B6FE-00A0C90F57DASome USB devices
13946BDD1FC1-810F-11D0-BEC7-08002BE2092FIEEE 1394 host controller
Image6BDD1FC6-810F-11D0-BEC7-08002BE2092FCameras and scanners
Keyboard4D36E96B-E325-11CE-BFC1-08002BE10318Keyboards
Modem4D36E96D-E325-11CE-BFC1-08002BE10318Modems
Mouse4D36E96F-E325-11CE-BFC1-08002BE10318Mice and pointing devices
Media4D36E96C-E325-11CE-BFC1-08002BE10318Audio and video devices
Net4D36E972-E325-11CE-BFC1-08002BE10318Network adapters
Ports4D36E978-E325-11CE-BFC1-08002BE10318Serial and parallel ports
SCSIAdapter4D36E97B-E325-11CE-BFC1-08002BE10318SCSI and RAID controllers
System4D36E97D-E325-11CE-BFC1-08002BE10318System buses, bridges, etc.
USB36FC9E60-C465-11CF-8056-444553540000USB host controllers and hubs

最后

以上就是复杂灯泡为你收集整理的WinFrom、C# 学习记录二 监听usb设备变化、获取usb设备信息的全部内容,希望文章能够帮你解决WinFrom、C# 学习记录二 监听usb设备变化、获取usb设备信息所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(92)

评论列表共有 0 条评论

立即
投稿
返回
顶部