首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c#中的系统驱动程序列表

c#中的系统驱动程序列表
EN

Stack Overflow用户
提问于 2017-11-23 08:07:06
回答 3查看 2.9K关注 0票数 2

我的工作是列出系统中安装的驱动程序,就像在设备管理器中一样。我从Win32_PnPSignedDriver获得了这个列表,但它没有提供图标。有什么方法可以找到吗?或者我必须为列表添加自定义图标。我想生成和设备管理器一样的输出,我在C/C++中找到了一些参考,但在c#中没有。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-11-28 07:08:41

下面是两个实用工具类DeviceClassDevice,它们演示了如何做到这一点。它们不使用WMI,而是使用带有p/invoke的setupapi (以及System.Drawing的Icon类)。我认为这个API是获得图标的唯一受支持的方法。然后您可以使用WMI (使用ids和类ids来获得更多信息,这次是使用WMI)。

下面是在Windows窗体中使用这些类与设备管理器( Device )的比较,正如您所看到的,它非常接近,但是类图标并不完全相同,我不知道为什么,我还没有研究过。

最后注意:正如预期的那样,一些设备有一个与类不同的图标,与类中的其他图标不同。我们可以看到,在第一个音频类中,这两个设备没有相同的图标。

以下是代码:

代码语言:javascript
复制
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        // This is a standard Form. I have added a TreeView control and an ImageList to the Form.
        // The image list is bound to the treeview, with ColorDepth set to Depth32Bit

        var classes = DeviceClass.Load(DeviceFiter.AllClasses | DeviceFiter.Present);
        foreach (var cls in classes)
        {
            var classNode = treeView1.Nodes.Add(cls.Description);
            imageList1.Images.Add(cls.Icon);
            classNode.ImageIndex = imageList1.Images.Count - 1;
            classNode.SelectedImageIndex = classNode.ImageIndex;

            foreach (var device in cls.Devices)
            {
                var deviceNode = classNode.Nodes.Add(device.Name);
                imageList1.Images.Add(device.Icon);
                deviceNode.ImageIndex = imageList1.Images.Count - 1;
                deviceNode.SelectedImageIndex = deviceNode.ImageIndex;
            }
            classNode.Expand();
        }

        // dispose (icons)
        foreach (var cls in classes)
        {
            foreach (var device in cls.Devices)
            {
                device.Dispose();
            }
            cls.Dispose();
        }
    }
}

public class DeviceClass : IDisposable, IComparable, IComparable<DeviceClass>
{
    private List<Device> _devices = new List<Device>();
    private Icon _icon;

    internal DeviceClass(Guid classId, string description)
    {
        ClassId = classId;
        Description = description;
    }

    public Guid ClassId { get; }
    public string Description { get; }
    public Icon Icon => _icon;
    public IReadOnlyList<Device> Devices => _devices;

    public static IReadOnlyList<DeviceClass> Load(DeviceFiter fiter)
    {
        var list = new List<DeviceClass>();
        var hdevinfo = SetupDiGetClassDevs(IntPtr.Zero, null, IntPtr.Zero, fiter);

        try
        {
            var data = new SP_DEVINFO_DATA();
            data.cbSize = Marshal.SizeOf<SP_DEVINFO_DATA>();
            int index = 0;
            while (SetupDiEnumDeviceInfo(hdevinfo, index, ref data))
            {
                index++;
                var classId = GetGuidProperty(hdevinfo, ref data, DEVPKEY_Device_ClassGuid);
                if (classId == Guid.Empty)
                    continue;

                string classDescription = GetClassDescription(classId);
                var cls = list.FirstOrDefault(c => c.ClassId == classId);
                if (cls == null)
                {
                    cls = new DeviceClass(classId, classDescription);
                    list.Add(cls);

                    SetupDiLoadClassIcon(ref classId, out IntPtr clsIcon, out int mini);
                    if (clsIcon != IntPtr.Zero)
                    {
                        cls._icon = Icon.FromHandle(clsIcon);
                    }
                }

                string name = GetStringProperty(hdevinfo, ref data, DEVPKEY_Device_FriendlyName);
                if (string.IsNullOrWhiteSpace(name))
                {
                    name = GetStringProperty(hdevinfo, ref data, DEVPKEY_Device_DeviceDesc);
                }

                Icon icon = null;
                SetupDiLoadDeviceIcon(hdevinfo, ref data, 16, 16, 0, out IntPtr devIcon);
                if (devIcon != IntPtr.Zero)
                {
                    icon = Icon.FromHandle(devIcon);
                }

                var dev = new Device(cls, name, icon);
                cls._devices.Add(dev);
            }

        }
        finally
        {
            if (hdevinfo != IntPtr.Zero)
            {
                SetupDiDestroyDeviceInfoList(hdevinfo);
            }
        }

        foreach (var cls in list)
        {
            cls._devices.Sort();
        }
        list.Sort();
        return list;
    }

    int IComparable.CompareTo(object obj) => CompareTo(obj as DeviceClass);
    public int CompareTo(DeviceClass other)
    {
        if (other == null)
            throw new ArgumentNullException(nameof(other));

        return Description.CompareTo(other.Description);
    }

    public void Dispose()
    {
        if (_icon != null)
        {
            _icon.Dispose();
            _icon = null;
        }
    }

    private static string GetClassDescription(Guid classId)
    {
        SetupDiGetClassDescription(ref classId, IntPtr.Zero, 0, out int size);
        if (size == 0)
            return null;

        var ptr = Marshal.AllocCoTaskMem(size * 2);
        try
        {
            if (!SetupDiGetClassDescription(ref classId, ptr, size, out size))
                throw new Win32Exception(Marshal.GetLastWin32Error());

            return Marshal.PtrToStringUni(ptr, size - 1);
        }
        finally
        {
            Marshal.FreeCoTaskMem(ptr);
        }
    }

    private static string GetStringProperty(IntPtr hdevinfo, ref SP_DEVINFO_DATA data, DEVPROPKEY pk)
    {
        SetupDiGetDeviceProperty(hdevinfo, ref data, ref pk, out int propertyType, IntPtr.Zero, 0, out int size, 0);
        if (size == 0)
            return null;

        var ptr = Marshal.AllocCoTaskMem(size);
        try
        {
            if (!SetupDiGetDeviceProperty(hdevinfo, ref data, ref pk, out propertyType, ptr, size, out size, 0))
                throw new Win32Exception(Marshal.GetLastWin32Error());

            return Marshal.PtrToStringUni(ptr, (size / 2) - 1);
        }
        finally
        {
            Marshal.FreeCoTaskMem(ptr);
        }
    }

    private static Guid GetGuidProperty(IntPtr hdevinfo, ref SP_DEVINFO_DATA data, DEVPROPKEY pk)
    {
        SetupDiGetDeviceProperty(hdevinfo, ref data, ref pk, out int propertyType, out Guid guid, 16, out int size, 0);
        return guid;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct SP_DEVINFO_DATA
    {
        public int cbSize;
        public Guid ClassGuid;
        public int DevInst;
        public IntPtr Reserved;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct DEVPROPKEY
    {
        public Guid fmtid;
        public int pid;
    }

    private const int ERROR_NOT_FOUND = 118;
    private const int ERROR_INSUFFICIENT_BUFFER = 122;

    private static readonly DEVPROPKEY DEVPKEY_Device_DeviceDesc = new DEVPROPKEY { fmtid = new Guid("a45c254e-df1c-4efd-8020-67d146a850e0"), pid = 2 };
    private static readonly DEVPROPKEY DEVPKEY_Device_FriendlyName = new DEVPROPKEY { fmtid = new Guid("a45c254e-df1c-4efd-8020-67d146a850e0"), pid = 14 };
    private static readonly DEVPROPKEY DEVPKEY_Device_Class = new DEVPROPKEY { fmtid = new Guid("a45c254e-df1c-4efd-8020-67d146a850e0"), pid = 9 };
    private static readonly DEVPROPKEY DEVPKEY_Device_ClassGuid = new DEVPROPKEY { fmtid = new Guid("a45c254e-df1c-4efd-8020-67d146a850e0"), pid = 10 };

    [DllImport("setupapi", CharSet = CharSet.Unicode)]
    private static extern IntPtr SetupDiGetClassDevs(IntPtr ClassGuid, [MarshalAs(UnmanagedType.LPWStr)] string Enumerator, IntPtr hwndParent, DeviceFiter Flags);

    [DllImport("setupapi", SetLastError = true)]
    private static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);

    [DllImport("setupapi", SetLastError = true)]
    private static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, int MemberIndex, ref SP_DEVINFO_DATA DeviceInfoData);

    [DllImport("setupapi", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool SetupDiGetClassDescription(ref Guid ClassGuid, IntPtr ClassDescription, int ClassDescriptionSize, out int RequiredSize);

    [DllImport("setupapi", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool SetupDiLoadClassIcon(ref Guid ClassGuid, out IntPtr LargeIcon, out int MiniIconIndex);

    [DllImport("setupapi", SetLastError = true)]
    private static extern bool SetupDiLoadDeviceIcon(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData,
        int cxIcon, int cyIcon, int Flags, out IntPtr hIcon);

    [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool SetupDiGetDeviceProperty(IntPtr DeviceInfoSet,
          ref SP_DEVINFO_DATA DeviceInfoData,
          ref DEVPROPKEY PropertyKey,
          out int PropertyType,
          IntPtr PropertyBuffer,
          int PropertyBufferSize,
          out int RequiredSize,
          int Flags);

    [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool SetupDiGetDeviceProperty(IntPtr DeviceInfoSet,
          ref SP_DEVINFO_DATA DeviceInfoData,
          ref DEVPROPKEY PropertyKey,
          out int PropertyType,
          out Guid PropertyBuffer,
          int PropertyBufferSize,
          out int RequiredSize,
          int Flags);
}

[Flags]
public enum DeviceFiter // DIGCF_* flags
{
    Default = 1,
    Present = 2,
    AllClasses = 4,
    Profile = 8,
    DeviceInterface = 16
}

public class Device : IDisposable, IComparable, IComparable<Device>
{
    internal Device(DeviceClass cls, string name, Icon icon)
    {
        Class = cls;
        Name = name;
        Icon = icon;
    }

    public string Name { get; }
    public DeviceClass Class { get; }
    public Icon Icon { get; private set; }

    public override string ToString() => Name;

    public void Dispose()
    {
        if (Icon != null)
        {
            Icon.Dispose();
            Icon = null;
        }
    }

    int IComparable.CompareTo(object obj) => CompareTo(obj as Device);
    public int CompareTo(Device other)
    {
        if (other == null)
            throw new ArgumentNullException(nameof(other));

        return Name.CompareTo(other.Name);
    }
}
票数 8
EN

Stack Overflow用户

发布于 2017-11-27 08:23:35

有一个很好的文章使用SHGetFileInfo函数来获取相关的图标,我建议研究一下。

您不能使用纯.Net或C#来完成它,在本文中您将需要这个dll。

编辑

也许这个MDSN设备信息会有帮助

票数 1
EN

Stack Overflow用户

发布于 2021-07-01 20:17:37

我认为我们中的许多人在“Simon的密码”上有一些错误。以下是他的修订代码:

代码语言:javascript
复制
public class DeviceClass : IDisposable, IComparable, IComparable<DeviceClass>
{
    private List<Device> _devices = new List<Device>();
    private Icon _icon;

    internal DeviceClass(Guid classId, string description)
    {
        ClassId = classId;
        Description = description;
    }

    public Guid ClassId { get; }
    public string Description { get; }
    public Icon Icon => _icon;
    public IReadOnlyList<Device> Devices => _devices;
  

    public static IReadOnlyList<DeviceClass> Load(DeviceFiter fiter)
    {
        var list = new List<DeviceClass>();
        var hdevinfo = SetupDiGetClassDevs(IntPtr.Zero, null, IntPtr.Zero, fiter);

        try
        {
            var data = new SP_DEVINFO_DATA();
            data.cbSize = System.Runtime.InteropServices.Marshal.SizeOf<SP_DEVINFO_DATA>();
            int index = 0;
            while (SetupDiEnumDeviceInfo(hdevinfo, index, ref data))
            {
                index++;
                var classId = GetGuidProperty(hdevinfo, ref data, DEVPKEY_Device_ClassGuid);
                if (classId == Guid.Empty)
                    continue;

                string classDescription = GetClassDescription(classId);
                var cls = list.FirstOrDefault(c => c.ClassId == classId);
                if (cls == null)
                {
                    cls = new DeviceClass(classId, classDescription);
                    list.Add(cls);
                    IntPtr clsIcon;
                    int mini;

                     SetupDiLoadClassIcon(ref classId, out clsIcon, out mini);
                     if (clsIcon != IntPtr.Zero)
                    {
                        cls._icon = Icon.FromHandle(clsIcon);
                    }
                }

                string name = GetStringProperty(hdevinfo, ref data, DEVPKEY_Device_FriendlyName);
                if (string.IsNullOrWhiteSpace(name))
                {
                    name = GetStringProperty(hdevinfo, ref data, DEVPKEY_Device_DeviceDesc);
                }

                Icon icon = null;
                IntPtr devIcon;
                SetupDiLoadDeviceIcon(hdevinfo, ref data, 16, 16, 0, out devIcon);
                if (devIcon != IntPtr.Zero)
                {
                    icon = Icon.FromHandle(devIcon);
                }

                var dev = new Device(cls, name, icon);
                cls._devices.Add(dev);
            }

        }
        finally
        {
            if (hdevinfo != IntPtr.Zero)
            {
                SetupDiDestroyDeviceInfoList(hdevinfo);
            }
        }

        foreach (var cls in list)
        {
            cls._devices.Sort();
        }
        list.Sort();
        return list;
    }

    int IComparable.CompareTo(object obj) => CompareTo(obj as DeviceClass);
    public int CompareTo(DeviceClass other)
    {
        if (other == null)
            throw new ArgumentNullException(nameof(other));

        return Description.CompareTo(other.Description);
    }

    public void Dispose()
    {
        if (_icon != null)
        {
            _icon.Dispose();
            _icon = null;
        }
    }

    private static string GetClassDescription(Guid classId)
    {
        int size = 0;
        SetupDiGetClassDescription(ref classId, IntPtr.Zero, 0, out size);
        if (size == 0)
            return null;

        var ptr = Marshal.AllocCoTaskMem(size * 2);
        try
        {
            if (!SetupDiGetClassDescription(ref classId, ptr, size, out size))
                throw new Win32Exception(Marshal.GetLastWin32Error());

            return Marshal.PtrToStringUni(ptr, size - 1);
        }
        finally
        {
            Marshal.FreeCoTaskMem(ptr);
        }
    }

    private static string GetStringProperty(IntPtr hdevinfo, ref SP_DEVINFO_DATA data, DEVPROPKEY pk)
    {
        int propertyType;
        int size;
        SetupDiGetDeviceProperty(hdevinfo, ref data, ref pk, out propertyType, IntPtr.Zero, 0, out size, 0);
        if (size == 0)
            return null;

        var ptr = Marshal.AllocCoTaskMem(size);
        try
        {
            if (!SetupDiGetDeviceProperty(hdevinfo, ref data, ref pk, out propertyType, ptr, size, out size, 0))
                throw new Win32Exception(Marshal.GetLastWin32Error());

            return Marshal.PtrToStringUni(ptr, (size / 2) - 1);
        }
        finally
        {
            Marshal.FreeCoTaskMem(ptr);
        }
    }
     
    private static Guid GetGuidProperty(IntPtr hdevinfo, ref SP_DEVINFO_DATA data, DEVPROPKEY pk)
    {
        int propertyType, size;
        Guid guid;
        SetupDiGetDeviceProperty(hdevinfo, ref data, ref pk, out  propertyType, out guid, 16, out size, 0);
        return guid;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct SP_DEVINFO_DATA
    {
        public int cbSize;
        public Guid ClassGuid;
        public int DevInst;
        public IntPtr Reserved;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct DEVPROPKEY
    {
        public Guid fmtid;
        public int pid;
    }

    private const int ERROR_NOT_FOUND = 118;
    private const int ERROR_INSUFFICIENT_BUFFER = 122;

    private static readonly DEVPROPKEY DEVPKEY_Device_DeviceDesc = new DEVPROPKEY { fmtid = new Guid("a45c254e-df1c-4efd-8020-67d146a850e0"), pid = 2 };
    private static readonly DEVPROPKEY DEVPKEY_Device_FriendlyName = new DEVPROPKEY { fmtid = new Guid("a45c254e-df1c-4efd-8020-67d146a850e0"), pid = 14 };
    private static readonly DEVPROPKEY DEVPKEY_Device_Class = new DEVPROPKEY { fmtid = new Guid("a45c254e-df1c-4efd-8020-67d146a850e0"), pid = 9 };
    private static readonly DEVPROPKEY DEVPKEY_Device_ClassGuid = new DEVPROPKEY { fmtid = new Guid("a45c254e-df1c-4efd-8020-67d146a850e0"), pid = 10 };

    [DllImport("setupapi", CharSet = CharSet.Unicode)]
    private static extern IntPtr SetupDiGetClassDevs(IntPtr ClassGuid, [MarshalAs(UnmanagedType.LPWStr)] string Enumerator, IntPtr hwndParent, DeviceFiter Flags);

    [DllImport("setupapi", SetLastError = true)]
    private static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);

    [DllImport("setupapi", SetLastError = true)]
    private static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, int MemberIndex, ref SP_DEVINFO_DATA DeviceInfoData);

    [DllImport("setupapi", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool SetupDiGetClassDescription(ref Guid ClassGuid, IntPtr ClassDescription, int ClassDescriptionSize, out int RequiredSize);

    [DllImport("setupapi", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool SetupDiLoadClassIcon(ref Guid ClassGuid, out IntPtr LargeIcon, out int MiniIconIndex);

    [DllImport("setupapi", SetLastError = true)]
    private static extern bool SetupDiLoadDeviceIcon(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData,
        int cxIcon, int cyIcon, int Flags, out IntPtr hIcon);

    [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool SetupDiGetDeviceProperty(IntPtr DeviceInfoSet,
          ref SP_DEVINFO_DATA DeviceInfoData,
          ref DEVPROPKEY PropertyKey,
          out int PropertyType,
          IntPtr PropertyBuffer,
          int PropertyBufferSize,
          out int RequiredSize,
          int Flags);

    [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool SetupDiGetDeviceProperty(IntPtr DeviceInfoSet,
          ref SP_DEVINFO_DATA DeviceInfoData,
          ref DEVPROPKEY PropertyKey,
          out int PropertyType,
          out Guid PropertyBuffer,
          int PropertyBufferSize,
          out int RequiredSize,
          int Flags);
}

[Flags]
public enum DeviceFiter // DIGCF_* flags
{
    Default = 1,
    Present = 2,
    AllClasses = 4,
    Profile = 8,
    DeviceInterface = 16
}

public class Device : IDisposable, IComparable, IComparable<Device>
{
    internal Device(DeviceClass cls, string name, Icon icon)
    {
        Class = cls;
        Name = name;
        Icon = icon;
    }

    public string Name { get; }
    public DeviceClass Class { get; }
    public Icon Icon { get; private set; }

    public override string ToString() => Name;

    public void Dispose()
    {
        if (Icon != null)
        {
            Icon.Dispose();
            Icon = null;
        }
    }

    int IComparable.CompareTo(object obj) => CompareTo(obj as Device);
    public int CompareTo(Device other)
    {
        if (other == null)
            throw new ArgumentNullException(nameof(other));

        return Name.CompareTo(other.Name);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47450396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档