3

How to check if target of a given path is a directory?

Say:

rem all these should work (by X: I mean a mapped UNC path)
set somepath=some\path
set somepath=c:\some\path
set somepath=x:\some\path
set somepath=\\server\some\path
set isdir=

rem now do some extremely complicated black magic to set %isdir%

if not _%isdir%_==__ (
    rem do the directory thing
)

It should work with as most cases as possible from these:

  • on Windows NT (i.e. not a Vista+ thing).
  • with UNC paths as well as local paths
  • with spaces in path
  • with or without trailing backslash at the end
  • in case contents are not accessible

In extreme cases like when it can't be told (permissions), the fallback value can be no, it's not a directory.

Alois Mahdal
  • 10,763
  • 7
  • 51
  • 69
  • You should have tagged your question better in order to give it the desired visibility – Pedro Rolo Jan 18 '12 at 11:40
  • 2
    This question is a duplicate question: http://stackoverflow.com/questions/138981/how-do-i-test-if-a-file-is-a-directory-in-a-batch-script – Pedro Rolo Jan 18 '12 at 11:49
  • You need to specify you want a UNC path. That's makes a huge difference in what you're asking. Also, are you trying to figure out of \some\path is a directory or a file? Or do you wish to only know if it exists? – Anthony Miller Jan 18 '12 at 17:26
  • @Mechaflash I'm asking whether the target is a directory or not. And I'm trying to find the correct way how to do it regardless if the parameter is local path, UNC path, a file, directory or whatever user could pass. But yes, I should have mentioned that. (editing...) – Alois Mahdal Jan 18 '12 at 17:53

4 Answers4

5

Try this advice from Microsoft:

You cannot use the if command to test directly for a directory, but the null (NUL) device does exist in every directory. As a result, you can test for the null device to determine whether a directory exists. The following example tests for the existence of a directory:

if exist c:\mydir\nul goto process'

For UNC paths, I came up with:

@echo off
for /D %%I IN (%1) DO for /F "tokens=1 delims=-r" %%J IN ("%%~aI") DO if %%J==d echo  %%I is a directory

Put this in a batch file - it needs to be called with a name of a given object you want to verify, e. g. myBat \\\myUncPath. You may also put a wildcard, it will then print all directories in a given path - \\\myUncPath\\* will print all dirs in \\\myUncPath

Note: This should work on Windows 2000 and later with command extensions enabled (not on NT4 unfortunately). I tested it on XP.

Alois Mahdal
  • 10,763
  • 7
  • 51
  • 69
wmz
  • 3,645
  • 1
  • 14
  • 22
  • As I have posted to the other answer: This unfortunately does not work for UNC paths: `exists \\server\share\dir\NUL` is never true. – Alois Mahdal Jan 18 '12 at 16:09
  • gets interesting :-) I've edited my answer to include your requirement – wmz Jan 18 '12 at 17:51
  • +1 I like the "UNC" solution. It should work for all cases, yes? – dbenham Jan 18 '12 at 20:08
  • @dbenham yes it works for all cases Alois specified with the exception of NT compatibility. You may also put setlocal enableextensions at top to make sure they are enabled – wmz Jan 18 '12 at 21:38
  • @user1123692 i think Alois is looking for a miracle script =D. You know... one that works across all platforms... maybe we need to make it work for OSX... SCO UNIX... even Windows 3.2 XD – Anthony Miller Jan 19 '12 at 14:30
  • @Mechaflash Yes, a miracle script. (For cmd.exe, I'd certainly not demand more than just one platform.) Unfortunately this wonderful programming language is so magical that you will soon find yourself use heavy magic even for the most fundamental tasks. :D – Alois Mahdal Jan 19 '12 at 22:59
2

To see if a UNC path exists:

set somepath=\some\path\NUL
CALL:2 "%somepath%"
GOTO:EOF

:2
PUSHD "%~dp1"
IF [%errorlevel%] == [0] (
  ECHO IT EXISTS
  POPD
) ELSE (
  ECHO IT DOES NOT EXIST
)

If it exists, it will create a network drive (Z if it's not already assigned) with the path and CD you into it, and return an errorlevel of 0. If it doesn't exist, the command fails, and returns an errorlevel of 1.

If you want to break out of the UNC path, use the command POPD

Anthony Miller
  • 15,101
  • 28
  • 69
  • 98
  • I can't see the part where Z: is created. Or does PUSHD do that automatically? Sounds scary... And what if all letters are already taken? – Alois Mahdal Jan 18 '12 at 18:13
  • PUSHD automatically assigns the drive letter (starting from the end of the alphabet). It's only temporary in the current CMD session, as long as you remember to call `POPD` afterwards. Worst-case however, if you don't call `POPD`, a logoff or restart will clear the temporarily assigned drive letter. As far as if all drive letters are used up, the command should fail. If A-Z are really used up on your system, you may want to look into using a macro app to access the network shares as opposed to using up drive allocations. Plus, the more network paths you have mapped, the more performance u lose – Anthony Miller Jan 18 '12 at 19:28
  • Also, it will only map available drive letters. If say you have x and y drives already assigned when mapping two paths, it will use z and w. – Anthony Miller Jan 18 '12 at 19:29
  • Your question force me to look up whether you can go over the A-Z limit. In case you were interested, here's a cool article for a work-around method. http://ask-leo.com/26_drives_is_there_a_way_around_the_26_drive_limit_in_windows.html – Anthony Miller Jan 18 '12 at 20:56
0

Here is my solution after many tests with if exist, pushd, dir /AD, etc...

@echo off
cd /d C:\
for /f "delims=" %%I in ('dir /a /ogn /b') do (
    call :isdir "%%I"
    if errorlevel 1 (echo F: %%~fI) else echo D: %%~fI
)
cmd/k

:isdir
echo.%~a1 | findstr /b "d" >nul
exit /b %errorlevel%

:: Errorlevel
:: 0 = folder
:: 1 = file or item not found
  • It works with files that have no extension
  • It works with folders named folder.ext
  • It works with UNC path
  • It works with double-quoted full path or with just the dirname or filename only.
  • It works even if you don't have read permissions
  • It works with Directory Links (Junctions).
  • It works with files whose path contains a Directory Link.
Amr Ali
  • 3,020
  • 1
  • 16
  • 11
0

You can check whether %somepath%\NUL exists:

if exist %somepath%\NUL set isdir=1
Joey
  • 344,408
  • 85
  • 689
  • 683