Только, что написал. Прямо из печки.
Без использования временных файлов. Извлечёт все диски на флэшке (эммм - до 5 дисков), даже если они не читаются Виндой и не имеют в данный момент присвоенного имени диска.
Просто положить батник в кодировке OEM 866 на флэшку.
chcp 866
@echo off
setlocal enabledelayedexpansion
set N=%~d0
mshta vbscript:Execute("CreateObject(""WScript.Shell"").Run ""cmd /v /c cd /d c:&for /l %%n in (0,1,5) do ( for /f """"usebackq"""" %%i in (`wmic logicaldisk where """"Name='!N!'"""" get DriveType`) do (if %%i==2 (mshta """"vbscript:CreateObject(""""Scripting.FileSystemObject"""").GetStandardStream(1).Write(CreateObject^(""""Shell.Application""""^).NameSpace^(17^).ParseName^(""""!N!""""^).InvokeVerb^(""""Eject""""^))&Close()"""")))"",0,false:close")
Если кому надо из винды, то вариант для понимания попроще. Просто замените значение переменной ImyaFleshki на нужное. С флэшки не работает.
chcp 866
@echo off
set "ImyaFleshki=Clover"
set operation=Eject
set fname=%~n0
setlocal enabledelayedexpansion
for /f "tokens=2 delims==" %%a in ('wmic logicaldisk where "DriveType=2 and VolumeName='%ImyaFleshki%'" get Name /value^|find "="') do (
set Name=%%a
:loop
for /f "tokens=2 delims==" %%i in ('wmic logicaldisk where "Name='!Name!'" get Description /value^|find "="') do set Description=%%i
for /f tokens^=1^ delims^=^" %%a in ("!Description!") do set Description=%%a
if "!Description!"=="Removable Disk" (
call :disconnect !Name! %operation% ret
set "Description="
goto :loop
) else ( call :msgBox "Ваше устройство '!ImyaFleshki!' отсоединено от компьютера. Теперь вы можете безопасно извлечь его."
goto :eof)
)
call :msgBox "Устройство '!ImyaFleshki!' не обнаружено в файловой системе."
setlocal disabledelayedexpansion
goto :eof
:disconnect [DirName] [Operation] [ret]
set command=CreateObject("Shell.Application").NameSpace(17).ParseName("%~1").InvokeVerb("%~2")
SetLocal EnableExtensions
for /f "UseBackQ tokens=* delims=" %%i in (`mshta "vbscript:CreateObject("Scripting.FileSystemObject").GetStandardStream(1).Write(%command%)&Close()"`) do set "%~3=OK"
SetLocal DisableExtensions
exit /B
:msgBox [msgText]
PowerShell -Command^
"[Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')|Out-Null;"^
"[System.Windows.Forms.MessageBox]::Show(\"%~1\", 'Извлечение флэш накопителя','OK','Exclamation')"
set %~2=OK
exit /B
Ну ... и извлечь все флэшки. Работать правильно будет только из Винды. Если лежит на флэшке - извлечёт только "чужие" накопители.
chcp 866
@echo off
set operation=Eject
setlocal enabledelayedexpansion
for /f "tokens=2 delims==" %%a in ('wmic logicaldisk where "DriveType=2" get Name /value^|find "="') do (
set Name=%%a
:loop
for /f "tokens=2 delims==" %%i in ('wmic logicaldisk where "Name='!Name!'" get Description /value^|find "="') do set Description=%%i
for /f tokens^=1^ delims^=^" %%a in ("!Description!") do set Description=%%a
if "!Description!"=="Removable Disk" (
call :disconnect !Name! %operation% ret
set "Description="
goto :loop
) else ( call :msgBox "Вы можете безопасно извлечь все флэшки."
goto :eof)
)
call :msgBox "В файловой системе не обнаружено флэш карт."
setlocal disabledelayedexpansion
goto :eof
:disconnect [DirName] [Operation] [ret]
set command=CreateObject("Shell.Application").NameSpace(17).ParseName("%~1").InvokeVerb("%~2")
SetLocal EnableExtensions
for /f "UseBackQ tokens=* delims=" %%i in (`mshta "vbscript:CreateObject("Scripting.FileSystemObject").GetStandardStream(1).Write(%command%)&Close()"`) do set "%~3=OK"
SetLocal DisableExtensions
exit /B
:msgBox [msgText]
PowerShell -Command^
"[Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')|Out-Null;"^
"[System.Windows.Forms.MessageBox]::Show(\"%~1\", 'Извлечение флэш накопителя','OK','Exclamation')"
set %~2=OK
exit /B