UEFI启动电脑,PE卸载引导盘符(esp),不让显示电脑中
本帖最后由 baosheng00 于 2023-4-6 15:48 编辑论坛搜索没有查到没有可以卸载ESP分区的盘符,特来求助!F:盘就是要卸载的引导分区!获取bcd位置不够准确,有没有更好的方法?
1.获取bcd位置,判断盘符,无法卸载
$gudingpan = DriveGetDrive ("FIXED")
For $i = 1 To $gudingpan
If FileExists($gudingpan [$i]&"\EFI\Microsoft\Boot\bcd") Then
$driveLetter=($gudingpan [$i])
EndIf
Next
$diskpartScript = "select volume " & $driveLetter & @CRLF & "remove letter=" & $driveLetter
; 运行diskpart命令
Run(@ComSpec & " /c echo " & $diskpartScript & " | diskpart")
2.mountvol.exe也无法删除盘符,其它盘可以正常删除
#include <Process.au3>
$gudingpan = DriveGetDrive ("FIXED")
For $i = 1 To $gudingpan
If FileExists($gudingpan [$i]&"\EFI\Microsoft\Boot\bcd") Then
$driveLetter=($gudingpan [$i])
EndIf
Next
_rundos("mountvol.exe " & $driveLetter & " /d")
3.使用批处理来删除,可以但是死板0分区,第一分区,如果不是无效
cmd /c "echo select disk 0 & echo select partition 1& echo remove & echo exit"|diskpart.exe
所以请大家帮忙一下,用AU3编写,UEFI启动后,windwos卸载引导分区?(不要用DiskGenius之类手动删除,这个我会)
目的就是隐藏驱动器不是嘛,可以用注册表隐藏驱动。这样资源管理器里就不能查看到这个盘符了。 gyp2000 发表于 2023-4-6 19:00
目的就是隐藏驱动器不是嘛,可以用注册表隐藏驱动。这样资源管理器里就不能查看到这个盘符了。
查过资料,是不是这两个位置,但都没有
保存了UEFI启动Windows系统时引导盘的盘符。在注册表路径HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment中,有一个名为SystemDrive的变量,它保存了系统盘的盘符。在UEFI启动时,这个变量会被设置为引导盘的盘符。
HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices键下的DosDevices中。其中,\Device\HarddiskVolume2表示引导盘的盘符
但都没有F盘的信息,应该F盘,进入PE桌面后加载的盘符,注册表不存在盘符
baosheng00 发表于 2023-4-6 19:30
查过资料,是不是这两个位置,但都没有
保存了UEFI启动Windows系统时引导盘的盘符。在注册表路径HKEY_ ...
进入HKEY_CURRENT_USER\SoftWare\microsoft\Windows\CurrentVersion\Policies\Explorer分支中。
在右窗口中新建一个二进值的键值名为“NoDrives”,
设定值为(十六进制),如下:
不隐藏任何盘 0x00000000
隐藏A盘 0x01000000
隐藏B盘 0x02000000
隐藏C盘 0x04000000
隐藏D盘 0x08000000
隐藏E盘 0x10000000
隐藏F盘 0x20000000
隐藏G盘 0x40000000
隐藏H盘 0x80000000 理论上用diskpart 也是可以隐藏esp,就是操作比较复杂。
需要先获取diskpart回显,然后分析回显数据找到需要操作的磁盘序号和分区序号,最后隐藏。 能不能用命令:mountvol.exe盘符 /d
msold5 发表于 2023-4-7 08:21
能不能用命令:mountvol.exe盘符 /d
帖子第二点
2.mountvol.exe也无法删除盘符,其它盘可以正常删除 本帖最后由 gyp2000 于 2023-4-8 10:53 编辑
baosheng00 发表于 2023-4-7 17:12
帖子第二点
2.mountvol.exe也无法删除盘符,其它盘可以正常删除
DISKPART 删除盘符的例子:
#include <AutoItConstants.au3>
#include <WinAPIFiles.au3>
Example()
Func Example()
Local $iPID, $aData, $PartList
$iPID = Run(@SystemDir & "\DISKPART.EXE", @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
StdinWrite($iPID, "LIST VOLUME" & @CRLF & "Exit" & @CRLF)
While ProcessExists($iPID)
Sleep(10)
WEnd
$aData = BinaryToString(StdoutRead($iPID, False, True))
$PartList = StringRegExp($aData, "(?m)^.*?卷\h{5}(\d)\h{5}()", 3)
For $s = 0 To UBound($PartList) - 1 Step 2
$aData = _WinAPI_GetDriveNumber($PartList[$s + 1] & ":")
ConsoleWrite("驱动器:" & $PartList[$s + 1] & " 盘序号:" & $aData & " 分区号:" & $aData & @CRLF)
If $PartList[$s + 1] = "E" Then DISKPART($aData, $aData)
;如果是驱动器E 则删除盘符
Next
EndFunc ;==>Example
Func DISKPART($DeviceNumber, $PartitionNumber)
Local $iPID, $aData
$iPID = Run(@SystemDir & "\DISKPART.EXE", @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
StdinWrite($iPID, "SELECT DISK " & $DeviceNumber & @CRLF & _
"SELECT PARTITION " & $PartitionNumber & @CRLF & _
"REMOVE ALL NOERR" & @CRLF & _
"Exit" & @CRLF)
While ProcessExists($iPID)
Sleep(10)
WEnd
$aData = BinaryToString(StdoutRead($iPID, False, True))
ConsoleWrite($aData)
EndFunc ;==>DISKPART
本帖最后由 gyp2000 于 2023-4-8 11:31 编辑
也可以正则直接提取磁盘容量,然后根据容量大小删除盘符。
不过win7 win8.1 win10 下的 DISKPART.EXE 返回信息可能不完全一样,一个正则无法适配所有系统。
如果用其他办法判断分区是否需要隐藏,那么只需要用 _WinAPI_GetDriveNumber 获取盘序号和分区号,
就可以调用 DISKPART.EXE 删除盘符了。
#include <AutoItConstants.au3>
#include <WinAPIFiles.au3>
Example()
Func Example()
Local $iPID, $aData, $PartList
$iPID = Run(@SystemDir & "\DISKPART.EXE", @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
StdinWrite($iPID, "LIST VOLUME" & @CRLF & "Exit" & @CRLF)
While ProcessExists($iPID)
Sleep(10)
WEnd
$aData = BinaryToString(StdoutRead($iPID, False, True))
ConsoleWrite($aData)
$PartList = StringRegExp($aData, "(?m)^.*?卷\h{5}\d\h{5}().*?磁盘分区\h*?(\d+)*\h*?MB", 3)
If @error Then Return
For $s = 0 To UBound($PartList) - 1 Step 2
If int($PartList[$s + 1]) > 100 Then ;如果分区容量大于 100MB 并且有盘符,则删除盘符
$aData = _WinAPI_GetDriveNumber($PartList[$s] & ":")
DISKPART($aData, $aData)
ConsoleWrite("驱动器:" & $PartList[$s] & " 盘序号:" & $aData & " 分区号:" & $aData & @CRLF)
EndIf
Next
EndFunc ;==>Example
Func DISKPART($DeviceNumber, $PartitionNumber)
Local $iPID
$iPID = Run(@SystemDir & "\DISKPART.EXE", @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
StdinWrite($iPID, "SELECT DISK " & $DeviceNumber & @CRLF & _
"SELECT PARTITION " & $PartitionNumber & @CRLF & _
"REMOVE ALL NOERR" & @CRLF & _
"Exit" & @CRLF)
While ProcessExists($iPID)
Sleep(10)
WEnd
$aData = BinaryToString(StdoutRead($iPID, False, True))
ConsoleWrite($aData)
EndFunc ;==>DISKPART
gyp2000 发表于 2023-4-8 10:33
DISKPART 删除盘符的例子:
谢谢,测试还是不行。
#include <AutoItConstants.au3>
#include <WinAPIFiles.au3>
#include <File.au3>
$drives = DriveGetDrive("FIXED")
$esp_drive = ""
For $i = 1 To $drives
$drive_fs = DriveGetFileSystem($drives[$i])
If $drive_fs = "FAT32" Or $drive_fs = "FAT16" Or $drive_fs = "FAT" Then
$bcd_file = $drives[$i] & "\EFI\Microsoft\Boot\BCD"
If FileExists($bcd_file) Then
$esp_drive = $drives[$i]
ExitLoop
EndIf
EndIf
Next
;MsgBox(16+0, "错误", $esp_drive,8)
Example()
Func Example()
Local $iPID, $aData, $PartList
$iPID = Run(@SystemDir & "\DISKPART.EXE", @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
StdinWrite($iPID, "LIST VOLUME" & @CRLF & "Exit" & @CRLF)
While ProcessExists($iPID)
Sleep(10)
WEnd
$aData = BinaryToString(StdoutRead($iPID, False, True))
$PartList = StringRegExp($aData, "(?m)^.*?卷\h{5}(\d)\h{5}()", 3)
For $s = 0 To UBound($PartList) - 1 Step 2
$aData = _WinAPI_GetDriveNumber($PartList[$s + 1] & ":")
ConsoleWrite("驱动器:" & $PartList[$s + 1] & " 盘序号:" & $aData & " 分区号:" & $aData & @CRLF)
If $PartList[$s + 1] = $esp_drive Then DISKPART($aData, $aData)
;如果是驱动器E 则删除盘符
Next
EndFunc ;==>Example
Func DISKPART($DeviceNumber, $PartitionNumber)
Local $iPID, $aData
$iPID = Run(@SystemDir & "\DISKPART.EXE", @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
StdinWrite($iPID, "SELECT DISK " & $DeviceNumber & @CRLF & _
"SELECT PARTITION " & $PartitionNumber & @CRLF & _
"REMOVE ALL NOERR" & @CRLF & _
"Exit" & @CRLF)
While ProcessExists($iPID)
Sleep(10)
WEnd
$aData = BinaryToString(StdoutRead($iPID, False, True))
ConsoleWrite($aData)
EndFunc ;==>DISKPART
Exit
$esp_drive,可以获取到,盘符,但函数 DISKPART()未执行
本帖最后由 gyp2000 于 2023-4-8 19:11 编辑
上边写的只是例子。如果打算直接调用还需要改一下。
#include <AutoItConstants.au3>
#include <WinAPIFiles.au3>
#include <File.au3>
$drives = DriveGetDrive("FIXED")
$esp_drive = ""
For $i = 1 To $drives
$drive_fs = DriveGetFileSystem($drives[$i])
If $drive_fs = "FAT32" Or $drive_fs = "FAT16" Or $drive_fs = "FAT" Then
$bcd_file = $drives[$i] & "\EFI\Microsoft\Boot\BCD"
If FileExists($bcd_file) Then
$esp_drive = $drives[$i]
ExitLoop
EndIf
EndIf
Next
DISKPART($esp_drive)
Func DISKPART($DriveNumber)
Local $iPID, $aData
$aData = _WinAPI_GetDriveNumber($DriveNumber)
If @error Then Return
$iPID = Run(@SystemDir & "\DISKPART.EXE", @SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
StdinWrite($iPID, "SELECT DISK " & $aData & @CRLF & _
"SELECT PARTITION " & $aData & @CRLF & _
"REMOVE ALL NOERR" & @CRLF & _
"Exit" & @CRLF)
While ProcessExists($iPID)
Sleep(10)
WEnd
$aData = BinaryToString(StdoutRead($iPID, False, True))
ConsoleWrite($aData)
EndFunc ;==>DISKPART
gyp2000 发表于 2023-4-8 18:19
上边写的只是例子。如果打算直接调用还需要改一下。
谢谢,试了还是不能卸载。叫ai写一个
; 生成 unmount_boot_drive.txt 文件
Func GenerateUnmountScript($sDriveLetter)
Local $sScriptPath = @TempDir & "\unmount_boot_drive.txt"
Local $sScriptContent = "select volume " & $sDriveLetter & @CRLF & "remove letter " & $sDriveLetter & @CRLF & "exit"
Local $hFile = FileOpen($sScriptPath, 2)
If $hFile = -1 Then Return False
FileWriteLine($hFile, $sScriptContent)
FileClose($hFile)
Return $sScriptPath
EndFunc
; 查找电脑引导盘符
Func FindBootDrive()
Local $sDriveLetter = ""
Local $aDrives = DriveGetDrive("ALL")
For $i = 1 To $aDrives
If DriveGetType($aDrives[$i]) = "Fixed" And StringInStr(FileGetAttrib($aDrives[$i]), "F") And FileExists($aDrives[$i] & "\EFI\Microsoft\Boot\BCD") Then
$sDriveLetter = StringUpper(StringLeft($aDrives[$i], 1))
ExitLoop
EndIf
Next
If $sDriveLetter <> "" Then Return GenerateUnmountScript($sDriveLetter)
Return False
EndFunc
; 卸载引导盘符
Func UnmountBootDrive()
Local $sScriptPath = FindBootDrive()
If $sScriptPath <> False Then
RunWait(@ComSpec & " /c diskpart /s " & $sScriptPath, @SystemDir, @SW_HIDE)
FileDelete($sScriptPath)
Return True
EndIf
Return False
EndFunc
页:
[1]