自动适配编码的U盘强制弹出工具
@echo off
setlocal enabledelayedexpansion
:: 自动适配编码:中文系统默认936(ANSI),避免乱码
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage" /v "ACP" | find "936" >nul
if !errorlevel! equ 0 (
chcp 936 >nul
) else (
chcp 65001 >nul
)
title USB设备安全移除工具
color 0A
:: 过滤系统盘(可根据实际情况补充,比如E:若为系统盘可添加)
set "exclude_drives=C: D:"
:: 防误报提示(首次运行告知用户)
cls
echo ========================================
echo USB设备安全移除工具
echo ========================================
echo 若杀软告警:本工具仅调用系统原生磁盘工具,无任何恶意!
echo 建议将本脚本添加到杀软「信任/白名单」后使用
echo.
timeout /t 3 >nul
:main
cls
echo ========================================
echo USB设备安全移除工具
echo ========================================
echo.
echo 正在检测USB移动存储设备...
echo ----------------------------------------
set usbcount=0
set "usbdrive="
:: 兼容所有Windows版本
for /f "skip=1 tokens=1,3 delims= " %%a in ('wmic logicaldisk get DeviceID^,DriveType 2^>nul') do (
set "drive=%%a"
set "drivetype=%%b"
:: 过滤空值、系统盘,只保留可移动(2)/固定(3)USB设备
if not "!drive!"=="" if not "!drivetype!"=="" (
echo !exclude_drives! | find /i "!drive!" >nul
if !errorlevel! neq 0 (
if "!drivetype!"=="2" or "!drivetype!"=="3" (
echo 盘符: !drive! (类型:!drivetype!)
set /a usbcount+=1
set "usbdrive!usbcount!=!drive!"
)
)
)
)
echo ----------------------------------------
echo.
if !usbcount!==0 (
echo 未检测到USB移动存储设备!
echo 请检查设备是否已连接/未被识别为系统盘。
echo.
pause >nul
goto main
)
if !usbcount!==1 (
echo 检测到 1 个USB设备
set "drive=!usbdrive1!"
goto select_method
) else (
echo 检测到 !usbcount! 个USB设备
)
:select_drive
echo.
echo 请选择要操作的设备:
for /l %%i in (1,1,!usbcount!) do (
echo %%i. 驱动器 !usbdrive%%i!
)
echo r. 重新扫描设备
echo x. 退出
echo f. 恢复丢失的USB盘符(若插拔后不显示)
echo.
set "choice="
set /p "choice=请输入选择: "
if /i "!choice!"=="x" goto exit
if /i "!choice!"=="r" goto main
if /i "!choice!"=="f" goto fix_drive_letter :: 新增:恢复盘符入口
set "isvalid=0"
for /l %%i in (1,1,!usbcount!) do (
if "!choice!"=="%%i" (
set "isvalid=1"
set "drive=!usbdrive%%i!"
)
)
if !isvalid!==0 (
echo 错误:无效的选择!
timeout /t 2 >nul
goto select_drive
)
:select_method
cls
echo ========================================
echo 正在操作驱动器 !drive!
echo ========================================
echo.
echo 请选择移除方式:
echo 1. 普通安全移除(推荐)
echo 2. 强制卸载(当程序占用时使用)
echo 3. 显示驱动器信息
echo 4. 返回选择其他驱动器
echo 5. 返回主菜单
echo.
set "method="
set /p "method=请选择(1-5): "
if "!method!"=="" (
echo 错误:请输入1-5之间的数字!
timeout /t 2 >nul
goto select_method
)
if "!method!"=="1" goto safe_eject
if "!method!"=="2" goto force_eject
if "!method!"=="3" goto show_info
if "!method!"=="4" goto select_drive
if "!method!"=="5" goto main
echo 无效选择!请输入1-5之间的数字
timeout /t 1 >nul
goto select_method
:safe_eject
echo.
echo 正在尝试安全移除 !drive! ...
echo.
:: 调用系统安全删除硬件面板
rundll32.exe shell32.dll,Control_RunDLL hotplug.dll,,0
echo 请在弹出的「安全删除硬件」窗口中选择 !drive! 对应的设备并移除。
echo.
pause >nul
goto select_method
:force_eject
echo.
echo [警告] 强制卸载可能导致数据丢失!
echo 请确保:
echo 1. !drive! 上无运行程序/打开文件
echo 2. 重要数据已备份
echo.
set "confirm="
set /p "confirm=确定强制卸载 !drive! 吗?(Y/N): "
if /i not "!confirm!"=="Y" (
echo 已取消强制卸载操作。
timeout /t 1 >nul
goto select_method
)
echo.
echo ?? 正在请求管理员权限执行强制卸载(请在UAC弹窗中点击「是」)...
echo.
:: diskpart脚本仅卸载卷,不删除盘符
set "tmpfile=%temp%\usb_eject_%random%.tmp"
echo select volume !drive:~0,1! > "!tmpfile!"
echo dismount volume force :: 仅强制卸载卷,保留盘符
echo exit >> "!tmpfile!"
:: 可见窗口执行diskpart
powershell -Command "$tmp='!tmpfile!'; Start-Process diskpart -ArgumentList '/s', $tmp -Verb RunAs -WindowStyle Normal -Wait" >nul 2>nul
if errorlevel 1 (
echo diskpart执行失败,尝试mountvol命令(仅卸载卷)...
:: mountvol改用/p参数卸载卷但保留盘符,可见窗口
powershell -Command "$drive='!drive!\'; Start-Process cmd -ArgumentList '/c mountvol', $drive, '/p' -Verb RunAs -WindowStyle Normal -Wait" >nul 2>nul
if errorlevel 1 (
echo.
echo [错误] 强制卸载失败!
echo 原因:1. 未授予管理员权限 2. 设备被系统占用 3. 盘符无效
) else (
echo.
echo [成功] !drive! 已强制卸载(mountvol),盘符已保留
echo 提示:重新插拔设备即可正常显示盘符
)
) else (
echo.
echo [成功] !drive! 已强制卸载(diskpart),盘符已保留
echo 提示:重新插拔设备即可正常显示盘符
)
:: 清理临时文件
del /f /q "!tmpfile!" >nul 2>nul
echo.
pause >nul
goto main
:: 恢复丢失的USB盘符,解决插拔后不显示的问题
:fix_drive_letter
cls
echo ========================================
echo 恢复USB设备丢失的盘符
echo ========================================
echo 请确保:USB设备已插入电脑(磁盘管理器能看到但无盘符)
echo.
set "fix_letter="
set /p "fix_letter=请输入要恢复的盘符(如E、F,仅输字母): "
if "!fix_letter!"=="" (
echo 错误:盘符不能为空!
timeout /t 2 >nul
goto select_drive
)
:: 生成恢复盘符的diskpart脚本
set "tmpfile=%temp%\usb_fix_%random%.tmp"
echo list volume > "!tmpfile!" :: 列出所有卷,方便用户确认
echo select volume where DriveType=2 :: 选择可移动设备卷
echo assign letter=!fix_letter! >> "!tmpfile!" :: 分配盘符
echo exit >> "!tmpfile!"
echo.
echo ?? 正在请求管理员权限恢复盘符(请在UAC弹窗中点击「是」)...
echo.
powershell -Command "$tmp='!tmpfile!'; Start-Process diskpart -ArgumentList '/s', $tmp -Verb RunAs -WindowStyle Normal -Wait" >nul 2>nul
del /f /q "!tmpfile!" >nul 2>nul
echo.
echo [操作完成] 已尝试为USB设备分配盘符 !fix_letter!:
echo 若仍不显示:
echo 1. 打开「此电脑→管理→磁盘管理」,手动为USB设备分配盘符
echo 2. 重新插拔USB设备
echo.
pause >nul
goto select_drive
:show_info
cls
echo ========================================
echo 驱动器 !drive! 详细信息
echo ========================================
echo.
:: 用PowerShell获取格式化信息(兼容所有系统)
echo 【基础信息】
powershell -Command "$drive='!drive!'; $vol=Get-Volume -DriveLetter $drive[0] -ErrorAction SilentlyContinue; if($vol){Write-Host '卷标:' $vol.FileSystemLabel; Write-Host '文件系统:' $vol.FileSystem; Write-Host '总容量:' ([math]::Round($vol.Size/1GB,2)) 'GB'; Write-Host '剩余容量:' ([math]::Round($vol.FreeSpace/1GB,2)) 'GB'} else {Write-Host '无法获取信息:盘符无效'}"
echo.
echo 【系统详细信息】
echo ----------------------------------------
::直接在批处理执行fsutil,避免PowerShell嵌套导致的路径错误
if exist "!drive!\" (
fsutil fsinfo volumeinfo "!drive!" 2>nul
if errorlevel 1 (
echo [提示] 无法读取卷详细信息,可能原因:
echo 1. 设备被系统占用/无读取权限
echo 2. 设备为加密盘(如BitLocker)
echo 3. 设备分区损坏/未格式化
)
) else (
echo [提示] 盘符 !drive! 路径不存在,可能设备已被卸载/损坏
)
echo.
pause >nul
goto select_method
:exit
cls
echo ========================================
echo 感谢使用USB设备安全移除工具
echo ========================================
echo ?? 若杀软仍告警,可将本脚本添加到杀软白名单
echo.
echo 正在退出...
timeout /t 2 >nul
exit /b