SetupApi 如何获取 未安装驱动的设备的 硬件ID
本帖最后由 yhxhappy 于 2010-6-4 19:00 编辑第一次发贴, 标题什么起都觉得怪
以下代码是我修改后发上来的,本意并不是取得设备名并显示出来,只供参考#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <GuiTreeView.au3>
#include <SetupApi.au3>
Global $aClass = _CM_Enumerate_Classes()
Local $HardwareID
Local $Class
_HardwareScan()
_ArraySort($Class)
_ArraySort($HardwareID)
_GUI()
Func _HardwareScan()
Local $Noclass = "{8ECC055D-047F-11D1-A537-0000F8753ED1}";|非即插即用驱动程序
For $i = 1 To $aClass
If $aClass[$i] = $Noclass Then ContinueLoop
$Device = _CM_Enum_Device_Info($aClass[$i]) ;根据 Class 来枚举子项设备
If $Device = 0 Then ContinueLoop ;如果该 Class 下的子设备为 0 则跳过
For $a = 1 To $Device
$iStatus = _CM_Get_DevNode_Status($Device[$a]) ;根据设备号来判断设备是否在 设备管理器 内显示出来 $DN_NO_SHOW_IN_DM
If bitAND($iStatus, $DN_NO_SHOW_IN_DM) Then ContinueLoop
ReDim $HardwareID
$HardwareID = $aClass[$i] ;将设备所属的 Class 写进 $Hardware_ID
$HardwareID = $Device[$a]
$HardwareID = UBound($HardwareID)-1
If _ArraySearch($Class, $aClass[$i]) = -1 Then
ReDim $Class ;将本项设备的 Class 写进 $Class数组
$Class = $aClass[$i]
$Class = UBound($Class)-1
EndIf
Next
Next
EndFunc
Func _GUI()
$FORM = GUICreate("", 600, 700)
$Tree = GUICtrlCreateTreeView(0, 0, 600, 700)
GUISetState(@SW_SHOW) ; 显示窗口
$hItem = GUICtrlCreateTreeViewItem(@ComputerName, $Tree)
For $i = 1 To $Class
$hItem2 = GUICtrlCreateTreeViewItem($Class[$i], $hItem)
For $a = 1 To $HardwareID
If $HardwareID[$a] = $Class[$i] Then
GUICtrlCreateTreeViewItem($HardwareID[$a], $hItem2)
EndIf
Next
Next
GUICtrlSetState($hItem, $GUI_EXPAND)
;运行窗口直到用户关闭
While 1
If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit
WEnd
EndFunc上面的代码 我是先枚举系统内全部可用的CLASS,再根据CLASS枚举全部的硬件,最后判断该硬件是否在设备管理器内显示,是则写进数组最后显示到GUI上
现在碰到的问题是,不知道如何识别 未安装驱动的设备。虽然在设备管理器里面是显示“未知设备”里面,但是查看注册表该设备并不属于任何CLASS,所以通过枚举CLASS的方法行不通
现在只能通过别的方式枚举设备了
还请各位大大能解答一下 关注,等待P版的到来 #include <SetupAPI.au3>
Local $sDelims = Random(1, 1000), $sDevices
; Scan for hardware changes.
_CM_Scan_Device_Changes("")
_FindDeviceRecur(_CM_Locate_DevNode(""))
$sDevices = StringSplit(StringTrimRight($sDevices, StringLen($sDelims)), $sDelims, 1)
_Arraydisplay($sDevices)
Func _FindDeviceRecur($hDevInst)
Local $aChild, $sDescr, $sClass
$aChild = _CM_Enumerate_Children($hDevInst)
For $i = 1 To $aChild
$hDevInst = _CM_Locate_DevNode($aChild[$i])
$sClass = _CM_Get_DevNode_Registry_Property($hDevInst, $CM_DRP_CLASS)
If ($sClass = "") Then
$sDescr = _CM_Get_Device_Display_Name_Ex($hDevInst)
$sDevices &= $sDescr & ", " & $aChild[$i] & $sDelims
EndIf
_FindDeviceRecur($hDevInst)
Next
EndFunc ;==>_FindDeviceRecur_CM_Enum_Device_Info的效率不如上面的快,因为它事先要创建设备信息集合,然后依次枚举集合中的设备,这是2个耗时的指令。
以上代码,_FindDeviceRecur从设备树根部开始,枚举所有设备,并获取设备的类别名称(CM_DRP_CLASS),如果类别名称为空,则可以认为这是没有安装驱动的设备。
开头那句_CM_Scan_Device_Changes如同设备管理器中的“扫描检测硬件改动”,可以检测到已经卸载的设备,这也是个耗时的指令。
最后,_Arraydisplay中显示的就是没有加载驱动程序的设备的名称及设备ID。
请下载最新的SetupApi.au3,原本的库中没有_CM_Get_Device_Display_Name_Ex函数。 - - |||
我把最新的SetupApi.au3贴到这里来吧,既然楼主第一次发主题帖就给帖子想了一个不错的标题,不应该浪费楼主的金钱了,貌似在UDF区下载一个附件就要30金钱。 支持P版,口水 感谢pusofalse
还知道体贴我等穷人!
我是想用上面的方法来扫描本机的硬件ID,再与自己做的驱动光盘上INI文件里面记录的ID比对,成功则根据光盘内INI文件记录参数静默安装
不想用EVEREST的原因是它生成硬件报告耗时长,而且涉及版权问题!
不知道pusofalse对于智能驱动安装,有没有更好的点子! SetupAPI.au3 提供3种驱动更新方式。
1、_CM_Install_DevInst_Ex,与设备管理器安装驱动的方式相同,可以指定光盘安装,也可以手动选择。
2、_CM_Install_Device_Driver,除了兼容第一种方式外,还可以指定多种更新标识,比如 静默安装。
3、_CM_Update_PnP_Device,指定ini文件,ini中定义安装参数。你所说的应该适于用这种方式安装。
_CM_Update_PnP_Device原型:
_CM_Update_PnP_Device($sDeviceID, $sInfPath, $iFlags, $hWnd = 0)
$sDeviceID - 要更新驱动的设备的硬件ID。
$sInfPath - INF路径。
$iFlags - 安装标识,一般指定为0即可。更多选项请参考http://msdn.microsoft.com/en-us/library/ff553534(VS.85).aspx
$hWnd - 父窗口句柄,可以指定为0。
硬件ID不同于设备范例ID,要获取一个设备的硬件ID,调用_CM_Get_DevNode_Registry_Property,传递CM_DRP_HARDWAREID属性值。
_CM_Update_PnP_Device,只能更新即插即用设备,对于非即插即用设备,用上面2种方法。 慢慢消化! 学习一下........................ 作个记号,有空看看 关于 setupapi.au3 出本书的事是刻不容缓! 不错,学习了 SetupApi 确实该出本书 消化中。。。。。。。。。。。。。。。。。。。。。。。。。 支持出书.......................
页:
[1]
2