(view source code of which.bat as plain text)
@ECHO OFF
:: Check for NT4 or later
IF NOT "%OS%"=="Windows_NT" GOTO Syntax
:: Check for XP or later
FOR /F "tokens=2 delims=[]" %%A IN ('VER') DO FOR /F "tokens=2" %%B IN ("%%~A") DO IF %%B LSS 5.1 GOTO Syntax
:: Check command line argument
IF "%~1"=="" GOTO Syntax
IF NOT "%~2"=="" IF /I NOT "%~2"=="/A" GOTO Syntax
ECHO.%1 | FINDSTR /R /C:"[:\\\*\?,;/]" >NUL && GOTO Syntax
:: If the specified command contains a dot, it is not a macro nor an internal command
ECHO.%1 | FIND "." >NUL && GOTO ExtCmd
:: Check if the command specified is a DOSKEY macro
FOR /F "tokens=1* delims==" %%A IN ('DOSKEY /MACROS 2^>NUL') DO (
IF /I "%~1"=="%%~A" (
ECHO.
ECHO -DOSKEY Macro-
IF /I NOT "%~2"=="/A" GOTO:EOF
)
)
:: Next, check if the command specified is an internal command; to do so
:: reliably we need SysInternals' STRINGS; if it isn't available, we'll
:: just check against a list of known internal commands, risking "false
:: positives" in older CMD versions (e.g. MAKELINK does not exist in XP,
:: but without STRINGS.EXE this batch file will still return "-CMD
:: internal command-"; when STRINGS.EXE IS available, the batch file would
:: return "-None-")
FOR %%A IN (APPEND ASSOC BREAK CALL CD CHCP CHDIR CLS COLOR COPY DATE DEL DIR DPATH ECHO ENDLOCAL ERASE EXIT FOR FTYPE GOTO IF KEYS MD MKDIR MKLINK MOVE PATH PAUSE POPD PROMPT PUSHD RD REM REN RENAME RMDIR SET SETLOCAL SHIFT START TIME TITLE TRUENAME TYPE VER VERIFY VOL) DO (
IF /I "%~1"=="%%~A" (
STRINGS.EXE /? >NUL 2>&1
IF ERRORLEVEL 1 (
REM * * * NOT TESTED :: may return a false positive * * *
ECHO.
ECHO -CMD Internal Command-
IF /I NOT "%~2"=="/A" GOTO:EOF
) ELSE (
REM * * * TESTED with STRINGS.EXE :: might still occasionally fail, though * * *
STRINGS.EXE "%ComSpec%" | FINDSTR.EXE /R /B /I /C:"%~1$" >NUL
IF NOT ERRORLEVEL 1 (
ECHO.
ECHO -CMD Internal Command-
IF /I NOT "%~2"=="/A" GOTO:EOF
)
)
)
)
:ExtCmd
SETLOCAL ENABLEDELAYEDEXPANSION
:: Search current directory first, then PATH, for the "pure"
:: file name itself or one of the extensions defined in PATHEXT.
:: Add quotes to match directory names with spaces as well.
:: This command line was partly rewritten by David Riemens.
SET SRCH_PATH=.\;%PATH%
SET Found=-None-
FOR %%A IN (.;%PathExt%) DO (
IF "!Found!"=="-None-" (
FOR %%B IN ("%~1%%~A") DO (
IF NOT "%%~$SRCH_PATH:B"=="" (
FOR %%C IN ("%%~$SRCH_PATH:B") DO SET Test=%%~xC
IF NOT "!Test!"=="" IF NOT "!Test!"=="." (
ECHO.%%~$SRCH_PATH:B
IF /I NOT "%~2"=="/A" (
ENDLOCAL
GOTO:EOF
)
)
)
)
)
)
:: No success so far...?
IF /I NOT "%~2"=="/A" ECHO -None-
:: Done
ENDLOCAL
GOTO:EOF
:Syntax
ECHO WHICH, Version 6.11
ECHO UNIX-like WHICH utility for Windows XP and later
ECHO.
ECHO Usage: WHICH progname [ /A ]
ECHO.
ECHO Where: progname is the name of the program to locate
ECHO /A lists all occurrences, not just the first one
ECHO.
ECHO Returns: "-DOSKEY Macro-", "-CMD Internal Command-", or the fully qualified
ECHO path to the first matching program found in the PATH, based on the
ECHO specified extension or the ones listed in PATHEXT; or "-None-".
ECHO.
ECHO Notes: progname MAY include extension; wildcards, drive, path NOT allowed.
ECHO This batch file first searches the list of DOSKEY macros, then CMD's
ECHO internal commands, then current directory, finally PATH for progname.
ECHO Only if SysInternals' STRINGS is available and in the PATH, CMD's
ECHO internal commands will be verified; e.g. even though MKLINK is not
ECHO available in XP at all, without STRINGS the command "WHICH MKLINK"
ECHO would still return "-CMD internal command-" anyway.
ECHO When the /A switch is used, nothing is returned when nothing is found
ECHO (unlike without /A switch, where "-None-" would be returned).
ECHO.
ECHO Written by David Riemens and Rob van der Woude
:: The things you need to do to make the text fit in 80 columns and 25 lines...
IF NOT "%OS%"=="Windows_NT" ECHO http://www.robvanderwoude.com
IF "%OS%"=="Windows_NT" SET /P "=http://www.robvanderwoude.com" < NUL
IF "%OS%"=="Windows_NT" EXIT /B 1
page last modified: 2024-04-16; loaded in 0.0078 seconds