以编程方式检测有故障或缺失的驱动程序
Posted
技术标签:
【中文标题】以编程方式检测有故障或缺失的驱动程序【英文标题】:Programmatically detect faulty or missing drivers 【发布时间】:2015-05-21 16:07:33 【问题描述】:我的任务是找到一种方法来检测有故障或丢失的驱动程序,以便我的程序可以安装一个更好的适用于我的系统的驱动程序。我一直在尝试的事情包括使用setupapi.dll
从注册表中获取值并尝试找到一些标志,让我知道驱动程序存在问题。在MSDN 上,我发现“其他设备”的类 GUID 是4d36e97e-e325-11ce-bfc1-08002be10318
。但是,如果我尝试枚举这些设备,我什么也得不到,即使我在设备管理器下看到该类别的设备。是否有其他 Windows API 可以让我通过某种方式识别此类设备或一般的驱动程序错误?我的代码如下:
static void Main(string[] args)
Guid displayClass = new Guid("4d36e97e-e325-11ce-bfc1-08002be10318");
SafeDevInfoHandle hDevInfo = NativeMethods.SetupDiGetClassDevs(ref displayClass,
null, IntPtr.Zero, DIGetClassFlags.DIGCF_PRESENT);
if (hDevInfo.IsInvalid)
throw new Win32Exception();
DevInfoData did = new DevInfoData();
did.size = Marshal.SizeOf(did);
for (uint i = 0; NativeMethods.SetupDiEnumDeviceInfo(hDevInfo, i, ref did); i++)
if (NativeMethods.SetupDiBuildDriverInfoList(hDevInfo, ref did, DriverType.SPDIT_COMPATDRIVER))
DriverInfoData drvData = new DriverInfoData();
drvData.Size = Marshal.SizeOf(drvData);
for (uint j = 0; NativeMethods.SetupDiEnumDriverInfo(hDevInfo, ref did, DriverType.SPDIT_COMPATDRIVER, j, ref drvData); j++)
Console.WriteLine(drvData.ToString());
else
throw new Win32Exception();
我也尝试使用SetupDiGetDeviceRegistryProperty
来获取特定属性,但对于很多设备而言,并非所有属性都存在。我希望能够拨打这个电话并让它返回SPDRP_INSTALL_STATE
,但我还没有收到这个电话的实际回复。
【问题讨论】:
澄清一下,对SetupDiEnumDeviceInfo
的调用是否在第一次调用时返回FALSE
(当i
为零时),错误代码为ERROR_NO_MORE_ITEMS
?您是否尝试过使用已知的 GUID,例如 GUID_DEVCLASS_MOUSE
,以确保您的代码按预期工作?
您可以通过使用DIGCF_ALLCLASSES
并为GUID 传递NULL
来枚举所有设备。如果您可以通过这种方式找到您的设备,则可以查找 GUID 以查看它是什么。另一个想法:可能是DIGCF_PRESENT
搞砸了你;我不确定在这种情况下是否将没有驱动程序的设备视为“存在”。
@HarryJohnston 我认为DIGCF_PRESENT
不适用于缺少的驱动程序可能是对的,但如果我尝试使用DIGCF_ALLCLASSES
,它似乎不会返回有效的设备句柄。至于您的第一个问题,对SetupDiEnumDeviceInfo
的调用返回true,并且与我传入的GUID 一起工作得很好,除非我尝试枚举“其他设备”的信息,或者“未知”类什么都没有出现。跨度>
DIGCF_ALLCLASSES
对我来说似乎工作正常,请参阅cms.waikato.ac.nz/~harry/allclasses.c
@HarryJohnston 好的,我得到了它的工作,但是它返回了我在我的机器上安装的每个驱动程序。我正在寻找“未知”类别中的设备,即可能未安装驱动程序的设备。
【参考方案1】:
documentation for SetupDiGetClassDevs 包含用于枚举“其他设备”的示例代码(示例 5)并包含以下注释:
您不能将 ClassGuid 参数设置为 GUID_DEVCLASS_UNKNOWN 来检测具有未知安装类的设备。相反,您必须遵循此示例。
在 DDK 中查找 GUID_DEVCLASS_UNKNOWN
,它与您发布的代码中的 GUID 相同。因此,您尝试使用的方法被记录为无效。
相反,使用DIGCF_ALLCLASSES
选项枚举所有设备,并为每个设备查找设备类。根据示例代码,对于您感兴趣的设备,查找设备类将失败并显示ERROR_NOT_FOUND
。
(根据您要达到的具体目标,可能还有其他方法会更好,例如,您可以尝试为每个设备查找 DEVPKEY_Device_ProblemCode
。我对所有可能性并不十分熟悉.)
【讨论】:
以上是关于以编程方式检测有故障或缺失的驱动程序的主要内容,如果未能解决你的问题,请参考以下文章
如何以编程方式检测 SuSE Linux 中的 sata 驱动器拔出?