[已解决] SetupAPI 在64位系统下获取 设备驱动版本 问题
本帖最后由 yhxhappy 于 2010-11-1 12:38 编辑现已通过其它方法解决取得驱动版本的问题。
如题!#include <SetupApi.au3>
Local $hDevs, $tDevInfo, $aDisplay = []
$hDevs = _SetupDiGetClassDevs($DIGCF_PRESENT, "Display")
While _SetupDiEnumDeviceInfo($hDevs, $aDisplay, $tDevInfo)
$aDisplay += 1
$sDescr = _SetupDiGetDeviceRegistryProperty($hDevs, $tDevInfo, $SPDRP_DEVICEDESC)
$sName = _SetupDiGetDeviceRegistryProperty($hDevs, $tDevInfo, $SPDRP_FRIENDLYNAME)
If $sName <> "" Then $sDescr = $sName
Redim $aDisplay[$aDisplay + 1]
$aDisplay[$aDisplay] = $sDescr ; 显卡型号
$aDisplay[$aDisplay] = _SetupDiGetDeviceInstanceID($hDevs, $tDevInfo) ; 设备范例ID
WEnd
_SetupDiDestroyDeviceInfoList($hDevs)
$Version = Get_Driver_Version($aDisplay)
MsgBox(0, "", "显卡型号:" & $aDisplay & @CRLF & "驱动版本:" & $Version & @CRLF & "范例ID:" & $aDisplay)
Exit
Func Get_Driver_Version($InstanceID)
If $InstanceID = "" Then Return "Unknown"
Local $hDevs,$tDevInfo, $tDrvInfo, $tDrvDetail, $sInf, $sDateVer
_SetupDiCreateDeviceDevs($InstanceID, $hDevs, $tDevInfo)
_SetupDiBuildDriverInfoList($hDevs, $tDevInfo)
_SetupDiSelectBestCompatDrv($hDevs, $tDevInfo)
_SetupDiGetSelectedDriver($hDevs, $tDevInfo, $tDrvInfo)
_SetupDiGetDriverInfoDetail($hDevs, $tDevInfo, $tDrvInfo, $tDrvDetail)
$sInf = DllStructGetData($tDrvDetail, "InfFileName")
$sDateVer = IniRead($sInf, "Version", "DriverVer", "Unknown")
If $sDateVer = "Unknown" Or $sDateVer = "" Then
Return "Unknown"
Else
$VersionArray = StringSplit($sDateVer, ",", 1)
If $VersionArray = 1 Then
Return "Unknown"
Else
While 1
If StringLeft($VersionArray, 1) <> " " Then ExitLoop
$VersionArray = StringTrimLeft($VersionArray, 1)
WEnd
Return $VersionArray
EndIf
EndIf
EndFunc以上部分脚本截取自pusofalse写的”FSeven_V47 设备管理器“,在32位的WINDOWS下可以通过设备范例ID取得驱动版本,但在64位系统下获取失败。
在系统设备管理器里有版本信息,不了解系统是如何获取的。
请pusofalse以及各位大大帮我看看! 没人看吗,自己顶! 回复 1# yhxhappy
楼主能提供解决方法上来吗? 本帖最后由 yhxhappy 于 2010-11-6 13:37 编辑
回复 3# hzxymkb
我发的帖子还是第一次被版主打分呢,很高兴。
下面是我解决的代码,有部分是从 pusofalse 写的”FSeven_V47 设备管理器“ 搬的
还是以取显卡驱动版本为例。我在32位和64位的WIN_2K, WIN_XP, WIN_VISTA, WIN_2003, WIN_2008, WIN_2008R2, WIN_7验证通过。#include <SetupApi.au3>
FindDeviceRecur(_CM_Locate_DevNode(""))
Func FindDeviceRecur($hDevInst)
$aChild = _CM_Enumerate_Children($hDevInst)
For $i = 1 To $aChild
$hDevInst = _CM_Locate_DevNode($aChild[$i])
$Class = _CM_Get_DevNode_Registry_Property($hDevInst, $CM_DRP_CLASS)
$sDescr = _CM_Get_DevNode_Registry_Property($hDevInst, 1)
$Version = Get_Driver_Version($hDevInst)
If $Class = "Display" Then MsgBox(0,"","显卡型号:" & $sDescr & @CRLF & @CRLF & "驱动版本:" & $Version)
;此处只是为了取显卡的信息,所以加了判断,去掉可以取所有硬件驱动版本信息
FindDeviceRecur($hDevInst)
Next
EndFunc
Func Get_Driver_Version($hDevInst)
$ClassGUID = _CM_Get_DevNode_Registry_Property($hDevInst, 10)
If $ClassGUID = "" Then Return "Unknown"
If @OSArch = "X86" Then
$Reg = "HKLM\SYSTEM\ControlSet001\Control\Class\"
Else
$Reg = "HKLM64\SYSTEM\ControlSet001\Control\Class\"
EndIf
$Version = RegRead($Reg & $ClassGUID, "DriverVersion")
If $Version = "" Then
Return "Unknown"
Else
Return $Version
EndIf
EndFunc 学习了!
谢谢分享 回复 4# yhxhappy
请问如果我的电脑里有一些驱动,他们的类名是一样的,我如何筛选他们【比如类名为system,一搜一大堆】 回复 6# maxf4
不太明白你问的意思。下面是一个类似设备管理器的脚本供参考#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <GuiTreeView.au3>
#include <SetupApi.au3>
$DMGUI = GUICreate("Device Manager", 800, 600)
$DMTree = GUICtrlCreateTreeView(1, 1, 800, 600)
_HardwareScan()
GUISetState()
While 1
If GUIGetMsg() = -3 Then Exit
WEnd
Func _HardwareScan() ;扫描本机硬件信息并将信息添加至 TREE 控件
Global $Hardware, $Class, $HWNum = 1
_FindDeviceRecur(_CM_Locate_DevNode(""))
ReDim $Hardware[$HWNum]
$Hardware = $HWNum-1
_ArraySort($Hardware, 0, 1, 0, 1)
_GUICtrlTreeView_DeleteAll($DMTree)
Local $ClassItemString = "", $hItem2, $icon, $v
$hItem = GUICtrlCreateTreeViewItem(@ComputerName, $DMTree) ;计算机名添加进 TREE控件
For $a = 1 To $Hardware
$GUID = $Hardware[$a]
$GUIDName = $Hardware[$a]
If Not StringInStr($ClassItemString, $GUIDName & "|") Then
$hItem2 = GUICtrlCreateTreeViewItem($GUIDName, $hItem) ;大类
$IconString = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\" & $GUID, "IconPath")
If $IconString <> "" Then
$tt = StringSplit($IconString, ",")
If Not @error And $tt = 2 Then
;If $GUID = "{4d36e968-e325-11ce-bfc1-08002be10318}" Or $GUID = "{eec5ad98-8080-425f-922a-dabf3de3f69a}" Then ;显卡及便捷设备图标
;$icon = @ScriptDir & "\ICON\" & $GUID & ".ICO"
;$v = 0
;Else
$icon = $tt
$v = $tt
;EndIf
_GUICtrlTreeView_SetIcon($DMTree, $hItem2, $icon, $v)
EndIf
EndIf
$ClassItemString &= $GUIDName & "|"
EndIf
$hItem3 = GUICtrlCreateTreeViewItem($Hardware[$a], $hItem2) ;硬件添加进 TREE内的大类,如显卡设备属于 显示适配器 类
_GUICtrlTreeView_SetIcon($DMTree, $hItem3, $icon, $v)
$hItem4 = GUICtrlCreateTreeViewItem("Version: " & $Hardware[$a], $hItem3)
_GUICtrlTreeView_SetIcon($DMTree, $hItem4, $icon, $v)
Next
GUICtrlSetState($hItem, $GUI_EXPAND) ;展开父项
EndFunc
Func _FindDeviceRecur($hDevInst) ;找到并将符合条件的设备添加进数组,此函数供 _HardwareScan() 函数调用
$aChild = _CM_Enumerate_Children_Ex($hDevInst, 0)
For $i = 1 To $aChild
$hDevInst = _CM_Locate_DevNode($aChild[$i])
$aChild[$i] = StringUpper($aChild[$i])
$iStatus = _CM_Get_DevNode_Status($hDevInst) ;根据设备号来判断设备是否在 设备管理器 内显示出来 $DN_NO_SHOW_IN_DM
If bitAND($iStatus, $DN_NO_SHOW_IN_DM) Then ContinueLoop
$CLASSGuid = _CM_Get_DevNode_Registry_Property($hDevInst, $CM_DRP_CLASSGUID) ;根据设备ID取得该设备所属的CLASS
If $CLASSGuid = "{8ECC055D-047F-11D1-A537-0000F8753ED1}" Then ContinueLoop ;非即插即用设备 排除
$DEVName = _CM_Get_DevNode_Registry_Property($hDevInst, $CM_DRP_FRIENDLYNAME) ;设备名称
If $DEVName = "" Then $DEVName = _CM_Get_DevNode_Registry_Property($hDevInst, $CM_DRP_DEVICEDESC) ;设备名称
$GetClass = _CM_Get_DevNode_Registry_Property($hDevInst, $CM_DRP_CLASS) ;根据设备ID取得该设备所属的CLASS
$GetService = _CM_Get_DevNode_Registry_Property($hDevInst, $CM_DRP_SERVICE)
$tStatus = _CM_Query_Device_Problem($hDevInst) ;根据设备号返回设备状态代码
$CLASSName = _SetupDiGetClassDescription($CLASSGuid)
$Hardware[$HWNum] = _SetupDiGetClassDescription($CLASSGuid) ;将设备所属的 Class 中文名称
$Hardware[$HWNum] = $DEVName ;将设备名称 写进数组
$Hardware[$HWNum] = _Get_Driver_Version($hDevInst) ;驱动版本
$Hardware[$HWNum] = $CLASSGuid ;
$HWNum += 1
_FindDeviceRecur($hDevInst)
Next
EndFunc
Func _Get_Driver_Version($hDevInst)
$ClassGUID = _CM_Get_DevNode_Registry_Property($hDevInst, 10)
If $ClassGUID = "" Then Return "Unknown"
If @OSArch = "X86" Then
$Reg = "HKLM\SYSTEM\ControlSet001\Control\Class\"
Else
$Reg = "HKLM64\SYSTEM\ControlSet001\Control\Class\"
EndIf
$Version = RegRead($Reg & $ClassGUID, "DriverVersion")
If $Version = "" Then
Return "Unknown"
Else
Return $Version
EndIf
EndFunc 哇个坟,给其他遇到类似问题的人一个解决方法。
楼主代码无需任何更改,第一行增加 #PRE_UseX64=n 已32位方式运行程序即可。 回复 8# nmgwddj
我都是用AUTOIT官网下载的原版软件,加这个参数能用吗?我一直认为这些参数是汉化版才行的。 回复 9# yhxhappy
其实就是编译为32位就可以了。 回复 1# yhxhappy
您好,我用主楼的代码可以编译运行,为什么下面发的运行提示已重复定义的变量,我在论坛上搜了下,说忽略就可以编译,但是我这过不去,实在不知道为什么了.请问下是您用的是什么版本啊? 来回复求金币来着 来回复求金币来着.h
页:
[1]