53} How can I quietly test if a disk device is ready or not?
You
might first wish to revisit
item #9
about suppressing error messages.
@echo off & setlocal enableextensions
::
:: Check the usage
if "%1"=="" (
echo Usage: %~f0 [DiskDevice:]
goto :EOF)
for %%d in (a: b: c: d: e: f: g: h: i: j: k: l: m: n:
o: p: q: r: s: t: u: v: w: x: y: z:) do (
if /i "%%d"=="%1" goto _set)
echo Usage: %~f0 [DiskDevice:]
echo The DiskDevice must be A: - Z:
goto :EOF
::
:: Do the testing and set a relevant result environment variable
:_set
set ready=true
dir %1 > "%temp%\tmp$$$.dir" 2>&1
find "The device is not ready" "%temp%\tmp$$$.dir" > nul
if %errorlevel% EQU 0 set ready=false
find "The system cannot find the path specified" "%temp%\tmp$$$.dir" > nul
if %errorlevel% EQU 0 set ready=false
::
:: Show the result
if "%ready%"=="true" echo The device %1 is ready
if "%ready%"=="false" echo The device %1 is not ready
::
:: Clean up
if exist "%temp%\tmp$$$.dir" del "%temp%\tmp$$$.dir"
endlocal & goto :EOF
The output might be e.g.
D:\TEST>cmdfaq a:
The device a: is not ready
Writing a solution with subroutine formulation:
@echo off & setlocal enableextensions
for %%d in (a: b: c: d: e: f: g: h: i: j: k: l: m: n:
o: p: q: r: s: t: u: v: w: x: y: z:) do (
call :CheckDevice %%d error_
if defined error_ (
echo Drive %%d is not ready or there is no media in it
) else (echo Drive %%d is ready)
)
endlocal & goto :EOF
::
:CheckDevice
name_ error_
setlocal enableextensions
set name_=%~1
set err_=
dir "%name_%" 2>&1 | find "The device is not ready" > nul
if %errorlevel% EQU 0 set err_=true
dir "%name_%" 2>&1 | find "Invalid drive specification" > nul
if %errorlevel% EQU 0 set err_=true
dir "%name_%" 2>&1 | find "The system cannot find the" > nul
if %errorlevel% EQU 0 set err_=true
endlocal & set "%2=%err_%" & goto :EOF
The output might be e.g.
C:\_D\TEST>cmdfaq
Drive a: is not ready or there is no media in it
Drive b: is not ready or there is no media in it
Drive c: is ready
Drive d: is ready
Drive e: is not ready or there is no media in it
:
A VBS-aided solution to test the presense and the state of a drive:
@echo off & setlocal enableextensions
:: Build a Visual Basic Script
set skip=
set vbs_=%temp%\tmp$$$.vbs
findstr "'%skip%VBS" "%~f0" > "%vbs_%"
::
:: Run the Visual Basic Script
cscript //nologo "%vbs_%" "N:"
for %%f in ("%vbs_%") do if exist %%f del %%f
endlocal & goto :EOF
'
'................................................................
'The Visual Basic Script
'
Set arg = WScript.Arguments 'VBS
Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
Set dc = fso.Drives 'VBS
driveName=arg(0) 'VBS
If fso.DriveExists(driveName) Then 'VBS
WScript.StdOut.Write driveName & " Found" 'VBS
Set d = fso.GetDrive(fso.GetDriveName(driveName)) 'VBS
If d.IsReady Then 'VBS
WScript.StdOut.WriteLine " (Ready)" 'VBS
Else 'VBS
WScript.StdOut.WriteLine " (Not ready)" 'VBS
End If 'VBS
Else 'VBS
WScript.Echo driveName & " not found" 'VBS
End If 'VBS
The output might be e.g.
C:\_D\TEST>cmdfaq
N: Found (Not ready)
The following code will list all the devices that are
ready
@echo off & setlocal enableextensions enabledelayedexpansion
for %%d in (a: b: c: d: e: f: g: h: i: j: k: l: m: n:
o: p: q: r: s: t: u: v: w: x: y: z:) do (
dir %%d\ > nul 2>&1
if !errorlevel! EQU 0 echo %%d
)
endlocal & goto :EOF
The output might be e.g.
C:\_D\TEST>cmdfaq
c:
d:
e:
The following code will list all the devices that
are
present
@echo off & setlocal enableextensions
(for %%d in (A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z) do ^
@fsutil fsinfo drivetype %%d:
) ^
| find /v "No such Root Directory"
endlocal & goto :EOF
The output might be e.g.
C:\_D\TEST>cmdfaq
A: - Removable Drive
C: - Fixed Drive
D: - Removable Drive
E: - Removable Drive
N: - Removable Drive
Z: - CD-ROM Drive
The present drives. With a VBS-aided script. Without the drive types.
@echo off & setlocal enableextensions
:: Build a Visual Basic Script
set skip=
set vbs_=%temp%\tmp$$$.vbs
findstr "'%skip%VBS" "%~f0" > "%vbs_%"
::
:: Run the Visual Basic Script
cscript //nologo "%vbs_%"
for %%f in ("%vbs_%") do if exist %%f del %%f
endlocal & goto :EOF
'
'................................................................
'The Visual Basic Script
'
Dim fso, d, dc 'VBS
Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
Set dc = fso.Drives 'VBS
For Each d in dc 'VBS
If d.IsReady = True Then 'VBS
Wscript.Echo "Drive " & d.DriveLetter & ": (Ready)" 'VBS
Else 'VBS
Wscript.Echo "Drive " & d.DriveLetter & ":" 'VBS
End If 'VBS
Next 'VBS
The output might be e.g.
C:\_D\TEST>cmdfaq
Drive A:
Drive C: (Ready)
Drive N:
Drive T: (Ready)
Drive Z: