75} How do I detect if an object is a file or a folder?
A command-line script only solution based on a Usenet news posting
by Ted Davis
@echo off & setlocal enableextensions
if "%~1"=="" (set object=NoPara & goto _echo)
if not exist "%~1" (
set object=notfound
) else (
set object=folder
dir "%~1" | find "<DIR>" > nul
if errorlevel 1 set object=file)
:_echo
echo The object is a %object%
endlocal & goto :EOF
A more complicated Visual Basic Script (VBScript) aided command line
script solution:
@echo off & setlocal enableextensions
::
:: Get the nameobject to be checked
set FName_=%~1
if "%FName_%"=="" (
echo.
echo Usage: %~f0 FName
goto :EOF
)
if not [%2]==[] (
echo.
echo Long file names must be in parentheses ^(^"^)
goto :EOF
)
::
:: Test the traditional way to see that the difference between
:: a file and a folder is not detected
if not exist "%FName_%" (
echo "%FName_%" not found
) else (
echo "%FName_%" found)
::
:: Build a Visual Basic Script
if not exist c:\mytemp mkdir c:\mytemp
findstr "'%skip%VBS" "%~f0" > c:\mytemp\tmp$$$.vbs
::
:: Run it with Microsoft Windows Script Host Version 5.6
cscript //nologo c:\mytemp\tmp$$$.vbs>c:\mytemp\tmp$$$.cmd
::
:: Call the CMD script made my the VBS script
call c:\mytemp\tmp$$$.cmd
::
:: Show the results
echo %FName_% %FNameStatus%
::
:: Clean up
for %%f in (c:\mytemp\tmp$$$.vbs c:\mytemp\tmp$$$.cmd) do del %%f
rmdir c:\mytemp
endlocal & goto :EOF
'
'................................................................
'The Visual Basic Script
'
Dim FSO, f 'VBS
Set WshShell = WScript.CreateObject("WScript.shell") 'VBS
FName=WshShell.ExpandEnvironmentStrings("%FName_%") 'VBS
' 'VBS
Set FSO=CreateObject("Scripting.FileSystemObject") 'VBS
If not (FSO.FileExists(FName) or FSO.FolderExists(FName)) Then 'VBS
WScript.Echo "@set FNameStatus=NotFound" 'VBS
WScript.Quit 'VBS
End If 'VBS
If FSO.FileExists(FName) Then 'VBS
Set f = FSO.GetFile(FName) 'VBS
End if 'VBS
If FSO.FolderExists(FName) Then 'VBS
Set f = FSO.GetFolder(FName) 'VBS
End if 'VBS
If (f.attributes and 16) Then 'VBS
WScript.Echo "@set FNameStatus=Folder" 'VBS
Else 'VBS
WScript.Echo "@set FNameStatus=File" 'VBS
End If 'VBS
However, maybe the simplest method is the following
(but for
non-network cases only)
@echo off & setlocal enableextensions
if "%~1"=="" (
echo Usage: %~0 [FileOrFolderName]
goto :EOF
)
::
if not exist "%~1" (
echo File or folder "%~1" not found
goto :EOF
)
if exist "%~1\" (
echo "%~1" is a folder
) else (
echo "%~1" is a file
)
endlocal & goto :EOF
Formulated slightly differently:
@echo off & setlocal enableextensions
if "%~1"=="" (
echo Usage: "%~f0" ["File or foldername", no backslash \]
goto :EOF)
if not exist "%~1" echo "%~1" not found
if exist "%~1" if not exist "%~1\" echo "%~1" is a file
if exist "%~1\" echo "%~1" is a folder
endlocal & goto :EOF
Another approach, for testing folder existence only
@echo off & setlocal enableextensions
if "%~1"=="" (
echo Usage: %~0 [FileOrFolderName]
goto :EOF)
dir /b /a:d "%~1" >nul 2>&1 &&(echo Folder found)||(echo Folder not found or is a file)
endlocal & goto :EOF
Warning: As explained in the earlier Item
#59
on post MS-DOS+Win../95/98/Me systems it is not advisable to
test for folder's existence with
if exist "%~1\nul" echo "%~1" is a folder
Warning, take two: If the folder/file can be a network one, then the
backslash \ method does not separate between a folder and a file.
Instead apply (this is getting awfully complicated)
@echo off & setlocal enableextensions
if "%~1"=="" (
echo Usage: %~0 [FileOrFolderName]
goto :EOF)
::
:: Testing
call :IsFolderFn "%~1" isfolder_
call :IsFileFn "%~1" isfile_
echo "%~f1" isfile_=%isfile_% isfolder_=%isfolder_%
endlocal & goto :EOF
::
:: Is it a folder
:: First the potential case of the root requires special treatment
:IsFolderFn
setlocal
if /i "%~d1"=="%~1" if exist "%~d1\" (
set return_=true& goto _ExitIsFolderFn)
if /i "%~d1\"=="%~1" if exist "%~d1" (
set return_=true& goto _ExitIsFolderFn)
set return_=
dir /a:d "%~1" 2>&1|find "<DIR>">nul
if %errorlevel% EQU 0 set return_=true
:_ExitIsFolderFn
endlocal & set "%2=%return_%" & goto :EOF
::
:: Is it just a file
:IsFileFn
setlocal
set return_=
if not exist "%~1" goto _ExitIsFileFn
call :IsFolderFn "%~1" isfold_
if defined isfold_ goto _ExitIsFileFn
dir /a:-d "%~1" 2>&1 > nul
if %errorlevel% EQU 0 set return_=true
:_ExitIsFileFn
endlocal & set "%2=%return_%" & goto :EOF