C#使用SetupAPI获取设备管理器相关信息

来源:互联网 发布:淘宝宝贝推荐模块多大 编辑:程序博客网 时间:2024/04/28 21:26


C# 使用SetupAPI获取windows系统设备管理器相关信息

            因工作需要,要获取windows系统上设备管理器里的设备信息、设备驱动信息。

            最开始是使用WMI来获取,但是测试后发现有一些不足:查询速度慢,查询信息分散,需要的信息没有,再就是耗时长,需要查询资料。

            之后在网上查询有没有更好的方法来获取,就找到了SetupAPI。可以通过几个函数来获取相关信息。网上的是示例大部分都是C++,少部分是C#,C#的示例功能也不多,我通过网上的C++、C#示例和代码测试,对使用SetupAPI获取设备信息做了点添加,如有不足、错误之处,希望大家多多指点,多多包涵,一起学习,一起进步。

           我要实现的功能是通过判断设备是否安装驱动程序来下载驱动进行更新。

          这里主要是获取设备管理器里的设备名称、设备ID、供应商、是否安装驱动等信息

        主要是是两个类一个是DeviceClasses 类,这个类用来获取设备的类型和设备类型的图标。内容和网上的一样未变动,只是加上了点注释。
     ///<summary>    /// 设备类型    /// </summary>    public class DeviceClasses    {        public static Guid ClassesGuid;        public const int MAX_SIZE_DEVICE_DESCRIPTION = 1000;        public const int CR_SUCCESS = 0x00000000;        public const int CR_NO_SUCH_VALUE = 0x00000025;        public const int CR_INVALID_DATA = 0x0000001F;        private const int DIGCF_PRESENT = 0x00000002;        private const int DIOCR_INSTALLER = 0x00000001;        private const int MAXIMUM_ALLOWED = 0x02000000;        public const int DMI_MASK = 0x00000001;        public const int DMI_BKCOLOR = 0x00000002;        public const int DMI_USERECT = 0x00000004;        /// <summary>        /// 定义了一个设备实例就是一个设备信息集合的成员        /// </summary>        [StructLayout(LayoutKind.Sequential)]        class SP_DEVINFO_DATA        {            public int cbSize;            public Guid ClassGuid;            public int DevInst;            public ulong Reserved;        }        /// <summary>        /// 提供每个类的GUID枚举本地机器安装的设备类        /// </summary>        /// <param name="ClassIndex"></param>        /// <param name="ClassGuid"></param>        /// <param name="Params"></param>        /// <returns></returns>        [DllImport("cfgmgr32.dll")]        private static extern UInt32 CM_Enumerate_Classes(UInt32 ClassIndex, ref Guid ClassGuid, UInt32 Params);        /// <summary>        /// 检索与类GUID相关联的类名        /// </summary>        /// <param name="ClassGuid"></param>        /// <param name="ClassName"></param>        /// <param name="ClassNameSize"></param>        /// <param name="RequiredSize"></param>        /// <returns></returns>        [DllImport("setupapi.dll")]        private static extern Boolean SetupDiClassNameFromGuidA(ref Guid ClassGuid, StringBuilder ClassName, UInt32 ClassNameSize, ref UInt32 RequiredSize);        /// <summary>        /// 获取一个指定类别或全部类别的所有已安装设备的信息        /// </summary>        /// <param name="ClassGuid"></param>        /// <param name="Enumerator"></param>        /// <param name="hwndParent"></param>        /// <param name="Flags"></param>        /// <returns></returns>        [DllImport("setupapi.dll")]        private static extern IntPtr SetupDiGetClassDevsA(ref Guid ClassGuid, UInt32 Enumerator, IntPtr hwndParent, UInt32 Flags);        /// <summary>        /// 销毁一个设备信息集合,并且释放所有关联的内存        /// </summary>        /// <param name="DeviceInfoSet"></param>        /// <returns></returns>        [DllImport("setupapi.dll")]        private static extern Boolean SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);        /// <summary>        /// 打开设备安装程序类的注册表项,设备接口类的注册表项,或一个特定类的子项。此函数打开本地计算机或远程计算机上指定的键。        /// </summary>        /// <param name="ClassGuid"></param>        /// <param name="samDesired"></param>        /// <param name="Flags"></param>        /// <param name="MachineName"></param>        /// <param name="Reserved"></param>        /// <returns></returns>        [DllImport("setupapi.dll")]        private static extern IntPtr SetupDiOpenClassRegKeyExA(ref Guid ClassGuid, UInt32 samDesired, int Flags, IntPtr MachineName, UInt32 Reserved);        /// <summary>        /// 获取设备信息集合的设备信息元素。        /// </summary>        /// <param name="DeviceInfoSet"></param>        /// <param name="MemberIndex"></param>        /// <param name="DeviceInfoData"></param>        /// <returns></returns>        [DllImport("setupapi.dll")]        private static extern Boolean SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, UInt32 MemberIndex, SP_DEVINFO_DATA DeviceInfoData);        /// <summary>        /// 取得指定项或子项的默认(未命名)值         /// </summary>        /// <param name="KeyClass"></param>        /// <param name="SubKey"></param>        /// <param name="ClassDescription"></param>        /// <param name="sizeB"></param>        /// <returns></returns>        [DllImport("advapi32.dll")]        private static extern UInt32 RegQueryValueA(IntPtr KeyClass, UInt32 SubKey, StringBuilder ClassDescription, ref UInt32 sizeB);        /// <summary>        /// 设备类型图标信息        /// </summary>        [StructLayout(LayoutKind.Sequential)]        public class SP_CLASSIMAGELIST_DATA        {            public int cbSize;            public string ImageList;            public ulong Reserved;        }        public struct RECT        {            long left;            long top;            long right;            long bottom;        }        /// <summary>        /// 载入图片        /// </summary>        /// <param name="hInstance"></param>        /// <param name="Reserved"></param>        /// <returns></returns>        [DllImport("user32.dll")]        public static extern int LoadBitmapW(int hInstance, ulong Reserved);        /// <summary>        /// 获取图标        /// </summary>        /// <param name="ClassImageListData"></param>        /// <returns></returns>        [DllImport("setupapi.dll")]        public static extern Boolean SetupDiGetClassImageList(out SP_CLASSIMAGELIST_DATA ClassImageListData);        /// <summary>        /// 绘制小图标        /// </summary>        /// <param name="hdc"></param>        /// <param name="rc"></param>        /// <param name="MiniIconIndex"></param>        /// <param name="Flags"></param>        /// <returns></returns>        [DllImport("setupapi.dll")]        public static extern int SetupDiDrawMiniIcon(Graphics hdc, RECT rc, int MiniIconIndex, int Flags);        /// <summary>        /// 检索指定类提供的小图标的索引。        /// </summary>        /// <param name="ClassGuid"></param>        /// <param name="MiniIconIndex"></param>        /// <returns></returns>        [DllImport("setupapi.dll")]        public static extern bool SetupDiGetClassBitmapIndex(Guid ClassGuid, out int MiniIconIndex);        /// <summary>        /// 加载小图标        /// </summary>        /// <param name="classGuid"></param>        /// <param name="hIcon"></param>        /// <param name="index"></param>        /// <returns></returns>        [DllImport("setupapi.dll")]        public static extern int SetupDiLoadClassIcon(ref Guid classGuid, out IntPtr hIcon, out int index);        /// <summary>        /// 枚举设备类型        /// </summary>        /// <param name="ClassIndex"></param>        /// <param name="ClassName">设备类型名称</param>        /// <param name="ClassDescription">设备类型说明</param>        /// <param name="DevicePresent"></param>        /// <returns></returns>        public static int EnumerateClasses(UInt32 ClassIndex, StringBuilder ClassName, StringBuilder ClassDescription, ref bool DevicePresent)        {            Guid ClassGuid = Guid.Empty;            IntPtr NewDeviceInfoSet;            UInt32 result;            SP_DEVINFO_DATA DeviceInfoData = new SP_DEVINFO_DATA();            bool resNam = false;            UInt32 RequiredSize = 0;            result = CM_Enumerate_Classes(ClassIndex, ref ClassGuid, 0);            DevicePresent = false;            SP_CLASSIMAGELIST_DATA imagelist = new SP_CLASSIMAGELIST_DATA();            if (result != CR_SUCCESS)            {                return (int)result;            }            resNam = SetupDiClassNameFromGuidA(ref ClassGuid, ClassName, RequiredSize, ref RequiredSize);            if (RequiredSize > 0)            {                ClassName.Capacity = (int)RequiredSize;                resNam = SetupDiClassNameFromGuidA(ref ClassGuid, ClassName, RequiredSize, ref RequiredSize);            }            NewDeviceInfoSet = SetupDiGetClassDevsA(ref ClassGuid, 0, IntPtr.Zero, DIGCF_PRESENT);            if (NewDeviceInfoSet.ToInt32() == -1)            {                DevicePresent = false;                return 0;            }            UInt32 numD = 0;            DeviceInfoData.cbSize = 28;            DeviceInfoData.DevInst = 0;            DeviceInfoData.ClassGuid = System.Guid.Empty;            DeviceInfoData.Reserved = 0;            Boolean res1 = SetupDiEnumDeviceInfo(            NewDeviceInfoSet,            numD,            DeviceInfoData);            if (!res1)            {                DevicePresent = false;                return 0;            }            SetupDiDestroyDeviceInfoList(NewDeviceInfoSet);            IntPtr KeyClass = SetupDiOpenClassRegKeyExA(                ref ClassGuid, MAXIMUM_ALLOWED, DIOCR_INSTALLER, IntPtr.Zero, 0);            if (KeyClass.ToInt32() == -1)            {                DevicePresent = false;                return 0;            }            UInt32 sizeB = MAX_SIZE_DEVICE_DESCRIPTION;            ClassDescription.Capacity = MAX_SIZE_DEVICE_DESCRIPTION;            UInt32 res = RegQueryValueA(KeyClass, 0, ClassDescription, ref sizeB);            if (res != 0) ClassDescription = new StringBuilder(""); //No device description            DevicePresent = true;            ClassesGuid = DeviceInfoData.ClassGuid;            return 0;        }    }
     然后是DeviceInfo类,这个类用来获取设备详细信息。里面改为了获取设备ID、供应商、是否安装驱动这个三个数据,然后就是加了个获取其它(未知)设备类型信息的函数,里面的其它(未知)设备判断处理不是很好,但是工作赶时间,暂时先这样写了。
    ///<summary>    /// 设备详细    /// </summary>    public class DeviceInfo    {        private const int DIGCF_ALLCLASSES = (0x00000004);        private const int DIGCF_PRESENT = (0x00000002);        private const int MAX_DEV_LEN = 1000;//返回值最大长度        private const int SPDRP_DEVICEDESC = (0x00000000);// DeviceDesc (R/W)        private const int SPDRP_HARDWAREID = (0x00000001);// HardwareID (R/W)        private const int SPDRP_COMPATIBLEIDS = (0x00000002);// CompatibleIDs (R/W)        private const int SPDRP_UNUSED0 = (0x00000003);// unused        private const int SPDRP_SERVICE = (0x00000004);// Service (R/W)        private const int SPDRP_UNUSED1 = (0x00000005);// unused        private const int SPDRP_UNUSED2 = (0x00000006);// unused        private const int SPDRP_CLASS = (0x00000007);// Class (R--tied to ClassGUID)        private const int SPDRP_CLASSGUID = (0x00000008);// ClassGUID (R/W)        private const int SPDRP_DRIVER = (0x00000009);// Driver (R/W)        private const int SPDRP_CONFIGFLAGS = (0x0000000A);// ConfigFlags (R/W)        private const int SPDRP_MFG = (0x0000000B);// Mfg (R/W)        private const int SPDRP_FRIENDLYNAME = (0x0000000C);// FriendlyName (R/W)        private const int SPDRP_LOCATION_INFORMATION = (0x0000000D);// LocationInformation (R/W)        private const int SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = (0x0000000E);// PhysicalDeviceObjectName (R)        private const int SPDRP_CAPABILITIES = (0x0000000F);// Capabilities (R)        private const int SPDRP_UI_NUMBER = (0x00000010);// UiNumber (R)        private const int SPDRP_UPPERFILTERS = (0x00000011);// UpperFilters (R/W)        private const int SPDRP_LOWERFILTERS = (0x00000012);// LowerFilters (R/W)        private const int SPDRP_BUSTYPEGUID = (0x00000013);// BusTypeGUID (R)        private const int SPDRP_LEGACYBUSTYPE = (0x00000014);// LegacyBusType (R)        private const int SPDRP_BUSNUMBER = (0x00000015);// BusNumber (R)        private const int SPDRP_ENUMERATOR_NAME = (0x00000016);// Enumerator Name (R)        private const int SPDRP_SECURITY = (0x00000017);// Security (R/W, binary form)        private const int SPDRP_SECURITY_SDS = (0x00000018);// Security=(W, SDS form)        private const int SPDRP_DEVTYPE = (0x00000019);// Device Type (R/W)        private const int SPDRP_EXCLUSIVE = (0x0000001A);// Device is exclusive-access (R/W)        private const int SPDRP_CHARACTERISTICS = (0x0000001B);// Device Characteristics (R/W)        private const int SPDRP_ADDRESS = (0x0000001C);// Device Address (R)        private const int SPDRP_UI_NUMBER_DESC_FORMAT = (0X0000001D);// UiNumberDescFormat (R/W)        private const int SPDRP_DEVICE_POWER_DATA = (0x0000001E);// Device Power Data (R)        private const int SPDRP_REMOVAL_POLICY = (0x0000001F);// Removal Policy (R)        private const int SPDRP_REMOVAL_POLICY_HW_DEFAULT = (0x00000020);// Hardware Removal Policy (R)        private const int SPDRP_REMOVAL_POLICY_OVERRIDE = (0x00000021);// Removal Policy Override (RW)        private const int SPDRP_INSTALL_STATE = (0x00000022);// Device Install State (R)        private const int SPDRP_LOCATION_PATHS = (0x00000023);// Device Location Paths (R)        private const int SPDRP_BASE_CONTAINERID = (0x00000024);// Base ContainerID (R)        private const int SPDRP_MAXIMUM_PROPERTY = (0x00000025);// Upper bound on ordinals        [StructLayout(LayoutKind.Sequential)]        private class SP_DEVINFO_DATA        {            public int cbSize;            public Guid ClassGuid;            public int DevInst;            public ulong Reserved;        };        [DllImport("setupapi.dll")]        private static extern Boolean SetupDiClassGuidsFromNameA(string ClassN, ref Guid guids, UInt32 ClassNameSize, ref UInt32 ReqSize);        [DllImport("setupapi.dll")]        private static extern IntPtr SetupDiGetClassDevsA(ref Guid ClassGuid, UInt32 Enumerator, IntPtr hwndParent, UInt32 Flags);        [DllImport("setupapi.dll")]        private static extern Boolean SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, UInt32 MemberIndex, SP_DEVINFO_DATA DeviceInfoData);        [DllImport("setupapi.dll")]        private static extern Boolean SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);        [DllImport("setupapi.dll")]        private static extern Boolean SetupDiGetDeviceRegistryPropertyA(IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, UInt32 Property, UInt32 PropertyRegDataType, StringBuilder PropertyBuffer, UInt32 PropertyBufferSize, IntPtr RequiredSize);        /// <summary>        /// 通过设备类型枚举设备信息        /// </summary>        /// <param name="DeviceIndex"></param>        /// <param name="ClassName"></param>        /// <param name="DeviceName"></param>        /// <returns></returns>        public static int EnumerateDevices(UInt32 DeviceIndex, string ClassName, StringBuilder DeviceName, StringBuilder DeviceID, StringBuilder Mfg, StringBuilder IsInstallDrivers)        {            UInt32 RequiredSize = 0;            Guid guid = Guid.Empty;            Guid[] guids = new Guid[1];            IntPtr NewDeviceInfoSet;            SP_DEVINFO_DATA DeviceInfoData = new SP_DEVINFO_DATA();            bool res = SetupDiClassGuidsFromNameA(ClassName, ref guids[0], RequiredSize, ref RequiredSize);            if (RequiredSize == 0)            {                //类型不正确                DeviceName = new StringBuilder("");                return -2;            }            if (!res)            {                guids = new Guid[RequiredSize];                res = SetupDiClassGuidsFromNameA(ClassName, ref guids[0], RequiredSize, ref RequiredSize);                if (!res || RequiredSize == 0)                {                    //类型不正确                    DeviceName = new StringBuilder("");                    return -2;                }            }            //通过类型获取设备信息            NewDeviceInfoSet = SetupDiGetClassDevsA(ref guids[0], 0, IntPtr.Zero, DIGCF_PRESENT);            if (NewDeviceInfoSet.ToInt32() == -1)            {                //设备不可用                DeviceName = new StringBuilder("");                return -3;            }            DeviceInfoData.cbSize = 28;            //正常状态            DeviceInfoData.DevInst = 0;            DeviceInfoData.ClassGuid = System.Guid.Empty;            DeviceInfoData.Reserved = 0;            res = SetupDiEnumDeviceInfo(NewDeviceInfoSet,                   DeviceIndex, DeviceInfoData);            if (!res)            {                //没有设备                SetupDiDestroyDeviceInfoList(NewDeviceInfoSet);                DeviceName = new StringBuilder("");                return -1;            }            DeviceName.Capacity = MAX_DEV_LEN;            DeviceID.Capacity = MAX_DEV_LEN;            Mfg.Capacity = MAX_DEV_LEN;            IsInstallDrivers.Capacity = MAX_DEV_LEN;            if (!SetupDiGetDeviceRegistryPropertyA(NewDeviceInfoSet, DeviceInfoData,            SPDRP_FRIENDLYNAME, 0, DeviceName, MAX_DEV_LEN, IntPtr.Zero))            {                res = SetupDiGetDeviceRegistryPropertyA(NewDeviceInfoSet,                 DeviceInfoData, SPDRP_DEVICEDESC, 0, DeviceName, MAX_DEV_LEN, IntPtr.Zero);                if (!res)                {                    //类型不正确                    SetupDiDestroyDeviceInfoList(NewDeviceInfoSet);                    DeviceName = new StringBuilder("");                    return -4;                }            }            //设备ID            bool resHardwareID = SetupDiGetDeviceRegistryPropertyA(NewDeviceInfoSet,             DeviceInfoData, SPDRP_HARDWAREID, 0, DeviceID, MAX_DEV_LEN, IntPtr.Zero);            if (!resHardwareID)            {                //设备ID未知                DeviceID = new StringBuilder("");                DeviceID.Append("未知");            }            //设备供应商            bool resMfg = SetupDiGetDeviceRegistryPropertyA(NewDeviceInfoSet,             DeviceInfoData, SPDRP_MFG, 0, Mfg, MAX_DEV_LEN, IntPtr.Zero);            if (!resMfg)            {                //设备供应商未知                Mfg = new StringBuilder("");                Mfg.Append("未知");            }            //设备是否安装驱动            bool resIsInstallDrivers = SetupDiGetDeviceRegistryPropertyA(NewDeviceInfoSet,             DeviceInfoData, SPDRP_DRIVER, 0, IsInstallDrivers, MAX_DEV_LEN, IntPtr.Zero);            if (!resIsInstallDrivers)            {                //设备是否安装驱动                IsInstallDrivers = new StringBuilder("");            }            //释放当前设备占用内存            SetupDiDestroyDeviceInfoList(NewDeviceInfoSet);            return 0;        }        /// <summary>        /// 获取未知设备信息        /// </summary>        /// <param name="DeviceIndex"></param>        /// <param name="ClassName"></param>        /// <param name="DeviceName"></param>        /// <returns></returns>        public static int EnumerateDevices(List<string> NameList, List<string> IDList, List<string> MfgList, List<string> TypeList, List<string> IsInstallDriversList)        {            Guid myGUID = System.Guid.Empty;            IntPtr hDevInfo = SetupDiGetClassDevsA(ref myGUID, 0, IntPtr.Zero, DIGCF_ALLCLASSES);            if (hDevInfo.ToInt32() == -1)            {                //设备不可用                return -3;            }            SP_DEVINFO_DATA DeviceInfoData = new SP_DEVINFO_DATA();            DeviceInfoData.cbSize = 28;            //正常状态            DeviceInfoData.DevInst = 0;            DeviceInfoData.ClassGuid = System.Guid.Empty;            DeviceInfoData.Reserved = 0;            UInt32 i;            for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, DeviceInfoData); i++)            {                //设备名称                StringBuilder DeviceName = new StringBuilder("");                //设备ID                StringBuilder DeviceID = new StringBuilder("");                //设备供应商                StringBuilder Mfg = new StringBuilder("");                //设备类型                StringBuilder DeviceType = new StringBuilder("");                //设备类型                StringBuilder IsInstallDrivers = new StringBuilder("");                DeviceName.Capacity = MAX_DEV_LEN;                DeviceID.Capacity = MAX_DEV_LEN;                DeviceType.Capacity = MAX_DEV_LEN;                Mfg.Capacity = MAX_DEV_LEN;                IsInstallDrivers.Capacity = MAX_DEV_LEN;                bool resName = SetupDiGetDeviceRegistryPropertyA(hDevInfo, DeviceInfoData, SPDRP_DEVICEDESC, 0, DeviceName, MAX_DEV_LEN, IntPtr.Zero);                if (!resName)                {                    //设备名称未知                    DeviceName = new StringBuilder("");                }                bool resClass = SetupDiGetDeviceRegistryPropertyA(hDevInfo, DeviceInfoData, SPDRP_CLASS, 0, DeviceType, MAX_DEV_LEN, IntPtr.Zero);                if (!resClass)                {                    //设备类型未知                    DeviceType = new StringBuilder("");                }                //设备ID                bool resHardwareID = SetupDiGetDeviceRegistryPropertyA(hDevInfo,                 DeviceInfoData, SPDRP_HARDWAREID, 0, DeviceID, MAX_DEV_LEN, IntPtr.Zero);                if (!resHardwareID)                {                    //设备ID未知                    DeviceID = new StringBuilder("");                }                //设备供应商                bool resMfg = SetupDiGetDeviceRegistryPropertyA(hDevInfo,                 DeviceInfoData, SPDRP_MFG, 0, Mfg, MAX_DEV_LEN, IntPtr.Zero);                if (!resMfg)                {                    //设备供应商未知                    Mfg = new StringBuilder("");                }                                bool resIsInstallDrivers = SetupDiGetDeviceRegistryPropertyA(hDevInfo,                 DeviceInfoData, SPDRP_DRIVER, 0, IsInstallDrivers, MAX_DEV_LEN, IntPtr.Zero);                if (!resIsInstallDrivers)                {                    //设备是否安装驱动                    IsInstallDrivers = new StringBuilder("");                }                if (string.IsNullOrEmpty(DeviceType.ToString()))                {                    if (!string.IsNullOrEmpty(DeviceName.ToString()) && !string.IsNullOrEmpty(DeviceID.ToString()))                    {                        TypeList.Add("其它设备");                        NameList.Add(DeviceName.ToString());                        IDList.Add(DeviceID.ToString());                        MfgList.Add(Mfg.ToString());                        IsInstallDriversList.Add(IsInstallDrivers.ToString());                    }                }            }            //释放当前设备占用内存            SetupDiDestroyDeviceInfoList(hDevInfo);            return 0;        }    }

0 0
原创粉丝点击