You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET中如何判断已安装驱动是否为第三方驱动

获取第三方已安装驱动的两种实现方案(C#/.NET)

一、基于WMI的实现

核心判断逻辑是利用Win32_DriverPackage类的IsBuiltIn属性:

  • IsBuiltIn=True:驱动是Windows系统镜像(Install.wim)内置的原生驱动
  • IsBuiltIn=False:驱动是Windows安装后另行安装的第三方驱动

如果需要关联到已加载的硬件驱动实例,可以结合Win32_PnPSignedDriver类,通过InfName属性关联驱动包与硬件实例。

C#代码示例(WMI)

using System.Management;

public static List<ThirdPartyDriver> GetThirdPartyDriversViaWmi()
{
    var thirdPartyDrivers = new List<ThirdPartyDriver>();

    // 查询所有非内置驱动包
    var driverPackageQuery = new ObjectQuery("SELECT * FROM Win32_DriverPackage WHERE IsBuiltIn = FALSE");
    using (var searcher = new ManagementObjectSearcher(driverPackageQuery))
    {
        foreach (ManagementObject package in searcher.Get())
        {
            var infName = package["InfName"]?.ToString();
            if (string.IsNullOrEmpty(infName)) continue;

            // 关联到已加载的PnP驱动实例(可选,用于获取硬件设备信息)
            var pnpQuery = new ObjectQuery($"SELECT * FROM Win32_PnPSignedDriver WHERE InfName = '{infName}'");
            using (var pnpSearcher = new ManagementObjectSearcher(pnpQuery))
            {
                foreach (ManagementObject pnpDriver in pnpSearcher.Get())
                {
                    thirdPartyDrivers.Add(new ThirdPartyDriver
                    {
                        DeviceName = pnpDriver["DeviceName"]?.ToString(),
                        DriverProvider = pnpDriver["DriverProviderName"]?.ToString(),
                        InfFileName = infName,
                        DriverVersion = pnpDriver["DriverVersion"]?.ToString(),
                        DeviceInstanceId = pnpDriver["DeviceInstanceId"]?.ToString()
                    });
                }
            }
        }
    }

    return thirdPartyDrivers;
}

public class ThirdPartyDriver
{
    public string DeviceName { get; set; }
    public string DriverProvider { get; set; }
    public string InfFileName { get; set; }
    public string DriverVersion { get; set; }
    public string DeviceInstanceId { get; set; }
}

注意:Win32_DriverPackage需要管理员权限才能完整枚举,部分受系统保护的驱动包可能无法访问。

二、基于SetupAPI.dll的实现

SetupAPI提供了更底层的驱动枚举能力,核心判断逻辑围绕驱动的来源路径和发布者展开:

  1. 非Microsoft发布的驱动直接判定为第三方驱动
  2. Microsoft发布的驱动,若其INF文件不在系统原生%Windows%\inf目录(而在%Windows%\System32\DriverStore\FileRepository下的第三方目录),则判定为后期安装的更新驱动(属于用户定义的第三方范畴)

C#代码示例(SetupAPI)

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public static class ThirdPartyDriverEnumerator
{
    // SetupAPI P/Invoke 定义
    [DllImport("setupapi.dll", SetLastError = true)]
    private static extern IntPtr SetupDiGetClassDevs(IntPtr classGuid, string enumerator, IntPtr hwndParent, uint flags);

    [DllImport("setupapi.dll", SetLastError = true)]
    private static extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet, uint memberIndex, ref SP_DEVINFO_DATA deviceInfoData);

    [DllImport("setupapi.dll", SetLastError = true)]
    private static extern bool SetupDiGetDeviceRegistryProperty(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, uint property, out uint propertyRegType, IntPtr propertyBuffer, uint propertyBufferSize, out uint requiredSize);

    [DllImport("setupapi.dll", SetLastError = true)]
    private static extern bool SetupDiEnumDriverInfo(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, uint driverType, uint memberIndex, ref SP_DRVINFO_DATA driverInfoData);

    [DllImport("setupapi.dll", SetLastError = true)]
    private static extern bool SetupDiGetDriverInfoDetail(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, ref SP_DRVINFO_DATA driverInfoData, ref SP_DRVINFO_DETAIL_DATA driverInfoDetailData, uint driverInfoDetailDataSize, out uint requiredSize);

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

    // 结构体定义
    [StructLayout(LayoutKind.Sequential)]
    private struct SP_DEVINFO_DATA
    {
        public uint cbSize;
        public Guid ClassGuid;
        public uint DevInst;
        public IntPtr Reserved;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct SP_DRVINFO_DATA
    {
        public uint cbSize;
        public uint DriverType;
        public IntPtr Reserved;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string Description;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string MfgName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string ProviderName;
        public System.Runtime.InteropServices.ComTypes.FILETIME DriverDate;
        public ulong DriverVersion;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct SP_DRVINFO_DETAIL_DATA
    {
        public uint cbSize;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string InfFileName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string InfSectionName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string HardwareId;
    }

    // 常量定义
    private const uint DIGCF_ALLCLASSES = 0x00000004;
    private const uint DIGCF_PRESENT = 0x00000002;
    private const uint SPDRP_DEVICEDESC = 0x00000000;
    private const uint SPDIT_COMPATDRIVER = 0x00000000;

    public static List<ThirdPartyDriver> GetThirdPartyDriversViaSetupApi()
    {
        var thirdPartyDrivers = new List<ThirdPartyDriver>();
        IntPtr deviceInfoSet = IntPtr.Zero;

        try
        {
            // 枚举所有已连接的设备
            deviceInfoSet = SetupDiGetClassDevs(IntPtr.Zero, null, IntPtr.Zero, DIGCF_ALLCLASSES | DIGCF_PRESENT);
            if (deviceInfoSet == IntPtr.Zero) throw new System.ComponentModel.Win32Exception();

            SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA();
            deviceInfoData.cbSize = (uint)Marshal.SizeOf(deviceInfoData);

            for (uint deviceIndex = 0; SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, ref deviceInfoData); deviceIndex++)
            {
                // 获取设备名称
                string deviceName = GetDeviceProperty(deviceInfoSet, ref deviceInfoData, SPDRP_DEVICEDESC);
                if (string.IsNullOrEmpty(deviceName)) continue;

                // 枚举设备的兼容驱动
                SP_DRVINFO_DATA driverInfoData = new SP_DRVINFO_DATA();
                driverInfoData.cbSize = (uint)Marshal.SizeOf(driverInfoData);

                for (uint driverIndex = 0; SetupDiEnumDriverInfo(deviceInfoSet, ref deviceInfoData, SPDIT_COMPATDRIVER, driverIndex, ref driverInfoData); driverIndex++)
                {
                    string infPath = GetDriverInfPath(deviceInfoSet, ref deviceInfoData, ref driverInfoData);
                    if (string.IsNullOrEmpty(infPath)) continue;

                    // 判断是否为第三方驱动
                    bool isThirdParty = false;
                    if (!driverInfoData.ProviderName.Equals("Microsoft", StringComparison.OrdinalIgnoreCase))
                    {
                        isThirdParty = true;
                    }
                    else
                    {
                        // 微软发布的驱动,检查是否为系统内置INF
                        string systemInfPath = Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\inf\";
                        if (!infPath.StartsWith(systemInfPath, StringComparison.OrdinalIgnoreCase))
                        {
                            isThirdParty = true;
                        }
                    }

                    if (isThirdParty)
                    {
                        thirdPartyDrivers.Add(new ThirdPartyDriver
                        {
                            DeviceName = deviceName,
                            DriverProvider = driverInfoData.ProviderName,
                            DriverVersion = ConvertDriverVersion(driverInfoData.DriverVersion),
                            InfFileName = System.IO.Path.GetFileName(infPath)
                        });
                    }
                }
            }
        }
        finally
        {
            if (deviceInfoSet != IntPtr.Zero)
            {
                SetupDiDestroyDeviceInfoList(deviceInfoSet);
            }
        }

        return thirdPartyDrivers;
    }

    private static string GetDeviceProperty(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, uint propertyId)
    {
        uint requiredSize = 0;
        SetupDiGetDeviceRegistryProperty(deviceInfoSet, ref deviceInfoData, propertyId, out _, IntPtr.Zero, 0, out requiredSize);
        if (requiredSize == 0) return null;

        IntPtr buffer = Marshal.AllocHGlobal((int)requiredSize);
        try
        {
            if (SetupDiGetDeviceRegistryProperty(deviceInfoSet, ref deviceInfoData, propertyId, out _, buffer, requiredSize, out _))
            {
                return Marshal.PtrToStringUni(buffer);
            }
            return null;
        }
        finally
        {
            Marshal.FreeHGlobal(buffer);
        }
    }

    private static string GetDriverInfPath(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, ref SP_DRVINFO_DATA driverInfoData)
    {
        uint requiredSize = 0;
        SP_DRVINFO_DETAIL_DATA detailData = new SP_DRVINFO_DETAIL_DATA();
        detailData.cbSize = (uint)Marshal.SizeOf(detailData);

        SetupDiGetDriverInfoDetail(deviceInfoSet, ref deviceInfoData, ref driverInfoData, ref detailData, detailData.cbSize, out requiredSize);
        if (SetupDiGetDriverInfoDetail(deviceInfoSet, ref deviceInfoData, ref driverInfoData, ref detailData, requiredSize, out _))
        {
            return detailData.InfFileName;
        }
        return null;
    }

    private static string ConvertDriverVersion(ulong version)
    {
        ushort major = (ushort)((version >> 48) & 0xFFFF);
        ushort minor = (ushort)((version >> 32) & 0xFFFF);
        ushort build = (ushort)((version >> 16) & 0xFFFF);
        ushort revision = (ushort)(version & 0xFFFF);
        return $"{major}.{minor}.{build}.{revision}";
    }
}

public class ThirdPartyDriver
{
    public string DeviceName { get; set; }
    public string DriverProvider { get; set; }
    public string DriverVersion { get; set; }
    public string InfFileName { get; set; }
}

三、验证逻辑准确性

可以通过对比Get-WindowsDriver -Online(无-All参数)的输出结果来验证,两种方案枚举的第三方驱动列表应与PowerShell命令输出一致。

内容的提问来源于stack exchange,提问作者ElektroStudios

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 10:10:29