找回密码
 加入
搜索
查看: 4140|回复: 4

[系统综合] 【自动卸载驱动】方面的问题(附源码)

[复制链接]
发表于 2011-5-26 12:09:42 | 显示全部楼层 |阅读模式
;将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 <> ""
发表于 2011-5-26 12:23:56 | 显示全部楼层
本帖最后由 zysanjing1 于 2011-5-26 12:29 编辑

这个需要到sky123.org论坛,看skyfree大大的封装与部署的教程,也许能找到你想要的答案
 楼主| 发表于 2011-5-26 12:30:50 | 显示全部楼层
中间有一段排除的代码,Mouse类(鼠标)、Keyboard类(键盘)、System类(系统设备)、egacyDriver类(遗留设备)。但我把网卡的类加上,就不行,不知道怎么回事
 楼主| 发表于 2011-5-26 15:25:46 | 显示全部楼层
$Flag 好像这个变量 程序里面没有用到,有没有效果一样
发表于 2011-5-26 16:08:01 | 显示全部楼层
去问Skyfree吧!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-14 14:29 , Processed in 0.076821 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表