;将devcon.exe的32位和64位版本均编译进本AU3程序
#Region ;**** 参数创建于 ACNWrapper_GUI ****
#AutoIt3Wrapper_Res_File_Add=devcon_x64.exe
#AutoIt3Wrapper_Res_File_Add=devcon_x86.exe
#EndRegion ;**** 参数创建于 ACNWrapper_GUI ****
;运行主函数,而后退出
_DrvUnins_Main()
Exit
;硬件驱动程序自动卸载,主程序
Func _DrvUnins_Main()
Local $TempDir = @WindowsDir & "\Temp\DrvUnins"
;规定一个临时文件夹
DirCreate($TempDir)
;获取当前操作系统中所有需卸载的硬件ID
Local $HwidList = _DrvUnins_ReadHwids()
Local $Hwids = _DrvUnins_TidyHwids($HwidList)
;根据当前操作系统位宽,装载合适的DevCon.exe
Local $DevCon = $TempDir & "\DevCon.exe"
If @OSArch = "x86" Then
FileInstall("DevCon_x86.exe", $DevCon, 1)
ElseIf @OSArch = "x64" Then
FileInstall("DevCon_x64.exe", $DevCon, 1)
EndIf
If Not (FileExists($DevCon)) Then
Return 0
EndIf
;还原注册表中记录的驱动文件所在位置键值到默认值
RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion", _
"DevicePath")
RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion", _
"DevicePath", "REG_EXPAND_SZ", "%SystemRoot%\inf")
;清理Windows\Inf下的搜有驱动预编译文件*.pnf
FileSetAttrib(@WindowsDir & "\inf\*.pnf", "-RSH")
FileDelete(@WindowsDir & "\inf\*.pnf")
;清理Windows\Inf下的所有Oem*.inf
FileSetAttrib(@WindowsDir & "\inf\oem*.inf", "-RSH")
FileDelete(@WindowsDir & "\inf\oem*.inf")
;预先处理上述项目可以一定程度上避免在驱动卸载过程中个别驱动自动重新安装
;并可以有效的减少对系统体积的占用
;根据硬件ID,使用DevCon.exe自动卸载所有驱动
_DrvUnins_Unins($Hwids, $DevCon)
;删除如下注册表键值,避免出现“本地连接2”
RegDelete("HKLM\SYSTEM\CurrentControlSet\Control\Network" & _
"{4D36E972-E325-11CE-BFC1-08002BE10318}")
RegWrite("HKLM\SYSTEM\CurrentControlSet\Control\Network" & _
"{4D36E972-E325-11CE-BFC1-08002BE10318}")
RegDelete("HKLM\SYSTEM\CurrentControlSet\Control\Network" & _
"{6BDD1FC5-810F-11D0-BEC7-08002BE2092F}")
RegWrite("HKLM\SYSTEM\CurrentControlSet\Control\Network" & _
"{6BDD1FC5-810F-11D0-BEC7-08002BE2092F}")
;服务调整
;如果使用的是Intel CPU机器执行的封装,将intelppm服务的启动方式改为手动
;否则,如果部署到AMD机器上,会出现宕机的情况
If RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\intelppm", _
'Start') <> '' Then
RegWrite("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\intelppm", _
'Start', 'REG_DWORD', '3')
EndIf
;删除驱动回滚
RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Reinstall")
;删除DeviceClasses 保存本机设备信息
RegDelete("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses")
;删除临时文件夹
DirRemove($TempDir, 1)
Return 1
EndFunc ;==>_DrvUnins_Main
;粗略读取所有需卸载设备的硬件ID
Func _DrvUnins_ReadHwids()
;定义一个名为$HwidList的二维动态数组,用于存储注册表键值和硬件ID
Local $HwidList[1][2], $p = 1
;定义根键
Local $RootKey = "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum"
;使用三重循环遍历$RootKey下的每个设备键值,获取HWID
Local $i = 1
While 1
Local $SubKey1 = RegEnumKey($RootKey, $i)
If @error = -1 Then ExitLoop
$SubKey1 = $RootKey & "" & $SubKey1
Local $j = 1
While 1
Local $SubKey2 = RegEnumKey($SubKey1, $j)
If @error = -1 Then ExitLoop
$SubKey2 = $SubKey1 & "" & $SubKey2
Local $k = 1
While 1
Local $SubKey3 = RegEnumKey($SubKey2, $k)
If @error = -1 Then ExitLoop
$SubKey3 = $SubKey2 & "" & $SubKey3
;$SubKey3为要目标键,读取此键值对应设备的所属类
Local $Cls = RegRead($SubKey3, "Class")
;定义一个标志,用于排除不需要卸载的设备
Local $Flag
If @OSVersion = "WIN_XP" = "WIN_2000" Or _
@OSVersion = "WIN_XP" Or _
@OSVersion = "WIN_2003" Then
;如果系统为Win5.x系列,保留的无需卸载的设备类为:
;Mouse类(鼠标)、Keyboard类(键盘)、
;System类(系统设备)、LegacyDriver类(遗留设备)
$Flag = $Cls <> "Mouse" And _
$Cls <> "Keyboard" And _
$Cls <> "System" And _
$Cls <> "LegacyDriver" And _
$Cls <> ""
Else
;如果系统为Win6.x系列,保留的无需卸载的设备类为:
;Mouse类(鼠标)、Keyboard类(键盘)、
;System类(系统设备)、LegacyDriver类(遗留设备)、
;Computer类(HAL)
$Flag = $Cls <> "Mouse" And _
$Cls <> "Keyboard" And _
$Cls <> "System" And _
$Cls <> "LegacyDriver" And _
$Cls <> "Computer" And _
$Cls <> ""
EndIf
;如果此设备的类不属于要排除的类型,则将它的键和ID写入数组$HwidList
;并重新定义数组,为数组增加一个元素长度
If $Flag Then
ReDim $HwidList[$p + 1][2]
$HwidList[$p][0] = $SubKey3
$HwidList[$p][1] = RegRead($SubKey3, "HardwareID")
$p += 1
EndIf
$k += 1
WEnd
$j += 1
WEnd
$i += 1
WEnd
Return $HwidList
EndFunc ;==>_DrvUnins_ReadHwids
;整理_DrvUnins_ReadHwids()函数生成的硬件ID列表
Func _DrvUnins_TidyHwids($HwidList)
;定义一个动态数组$tHwidList,用于暂时收集整理后的硬件ID
Local $tHwidList[1], $tp = 1
;由于$HwidList数组中读取到的硬件ID是以“@LF”分隔的字符串
;我们要获取每个ID,就要以“@LF”为分隔符来提取每个硬件ID
Local $i
For $i = 1 To UBound($HwidList, 1) - 1
Local $Hwids = $HwidList[$i][1]
If $Hwids <> "" Then
Local $tArr = StringSplit($Hwids, @LF)
If IsArray($tArr) And $tArr[0] > 1 Then
Local $j
For $j = 1 To UBound($tArr) - 1
ReDim $tHwidList[$tp + 1]
$tHwidList[$tp] = $tArr[$j]
$tp += 1
Next
EndIf
EndIf
Next
;_ArrayDisplay($tHwidList)
;删除数组中重复的硬件ID
Local $i, $j
For $i = 1 To UBound($tHwidList) - 2
For $j = $i + 1 To UBound($tHwidList) - 1
If $tHwidList[$i] <> "" And $tHwidList[$i] = $tHwidList[$j] Then
$tHwidList[$j] = ""
EndIf
Next
Next
;_ArrayDisplay($tHwidList)
;新建$Hwids数组,逐一读取$tHwidList中粗略整理的硬件ID
;不读取空元素,形成数据紧凑的数组$Hwids
Local $Hwids[1], $p = 1
Local $i
For $i = 1 To UBound($tHwidList) - 1
If $tHwidList[$i] <> "" Then
ReDim $Hwids[$p + 1]
$Hwids[$p] = $tHwidList[$i]
$p += 1
EndIf
Next
;_ArrayDisplay($Hwids)
;所有硬件ID读取并整理完毕,回传$Hwids数组
;$Hwids中包含了所有需要卸载设备的硬件ID
Return $Hwids
EndFunc ;==>_DrvUnins_TidyHwids
;使用DevCon.exe,根据硬件ID列表,逐一卸载驱动
Func _DrvUnins_Unins($Hwids, $DevCon)
;启用一个进度条来显示驱动卸载的进度
ProgressOn("驱动卸载", "正在卸载驱动...")
;遍历数组中的每个元素,执行卸载操作
Local $i
Local $Max = UBound($Hwids) - 1
Local $per = 1
For $i = 1 To $Max
;显示卸载进度
$per = Int($i / $Max * 100)
ProgressSet($per, StringReplace($Hwids[$i], "&", "&&"), "正在卸载驱动... (" & $per & "%)")
Local $Index
If $i < 10 Then
$Index = "0" & String($i)
Else
$Index = String($i)
EndIf
;使用DevCon.exe卸载驱动
RunWait($DevCon & " remove " & $Hwids[$i], "", @SW_HIDE)
Next
ProgressOff()
EndFunc ;==>_DrvUnins_Unins
以上是自动卸载驱动的代码,想问一下,如果我不想卸载网卡驱动,要改哪个地方。
我自己这样试了下,但是不成功 $Flag = $Cls <> "Mouse" And _
$Cls <> "Keyboard" And _
$Cls <> "System" And _
$Cls <> "LegacyDriver" And _
$Cls <> "Net" And _
$Cls <> ""
|