UNIX ports - WHICH

WHICH can help you find out which file is actually started when you type a command.
Its syntax is simple:

WHICH program_name

program_name may be specified with or without extension.
However, do not specify a drive or path.
Wildcards and spaces are not allowed either (except in the batch version, which does allow spaces as of version 3.00).

WHICH returns the fully qualified file name (drive:\path\filename.ext) for the specified program name.
It searches in the same order the command processor uses:

  1. It should first check if the specified command is an internal command; however, not all versions do check for internal commands; so far only my VBScript version does
  2. If a valid extension was given, it checks if the file resides in the current directory
  3. If no extension was given, it adds the extension .COM and checks if the file resides in the current directory
  4. If it wasn't found, the extension is changed to .EXE, .CMD (OS/2 and NT only) and .BAT consecutively, and the current directory is searched
  5. After that the first PATH entry is searched for each extension in the same order the current directory was searched
  6. Next, the second PATH entry is searched, etcetera
  7. As soon as the first valid entry is found, the search is aborted and the result displayed on screen

 

Download button
Download the ZIPped sources for all versions

 

Versions:

 

WHICH.BAT, Version 3.00 for Windows NT 4 / 2000 / XP

@ECHO OFF
:: Check Windows version
IF "%OS%"=="Windows_NT" (SETLOCAL) ELSE (GOTO Syntax)

:: Check command line argument
IF     "%~1"=="" GOTO Syntax
IF NOT "%~2"=="" GOTO Syntax
ECHO.%1 | FIND /V ":" | FIND /V "\" | FIND /V "*" | FIND /V "?" | FIND /V "," | FIND /V ";" | FIND /V "/"  | FIND "%~1" >NUL
IF ERRORLEVEL 1 GOTO Syntax

:: Initialize variable
SET Found=

:: 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.
SET Path="%CD%";"%Path:;=";"%"
:: This command line was rewritten by Yakov Azulay.
FOR %%A IN (%Path%) DO FOR %%B IN (.;%PathExt%) DO IF EXIST "%%~A.\%~1%%~B" CALL :Found "%%~A.\%~1%%~B"

:: Display the result
ECHO.
IF DEFINED Found (ECHO.%Found%) ELSE (ECHO -None-)

:: Done
GOTO End


:Found
:: Stop after finding the first match
IF DEFINED Found GOTO:EOF
:: Store the first match found
SET Found=%~f1
GOTO:EOF


:Syntax
ECHO.
ECHO WHICH, Version 3.00
ECHO UNIX-like WHICH utility for Windows NT 4 / 2000 / XP
ECHO.
ECHO Usage:  WHICH  program_name
ECHO.
ECHO You may specify the program_name with or without
ECHO extension, but no wildcards, nor drive, nor path.
ECHO.
ECHO Written by Yakov Azulay
ECHO and Rob van der Woude
ECHO http://www.robvanderwoude.com

:End
IF "%OS%"=="Windows_NT" ENDLOCAL

Back to the top of this page...

 

WHICH.KIX, Version 1.00

This KiXtart version also searches for DLLs, OCXs and SYS files.

; Check command line argument
If $search = "" OR InStr( $search, "?" )
	? "Which.kix,  Version 1.00"
	? "Locate the specified program file"
	? "Port of Unix' WHICH command" ?
	? "Usage:  KIX32  WHICH.KIX  $$SEARCH=filename[.ext]" ?
	? "Where:  " + Chr(34) + "filename" + Chr(34)
	" is a file name only: no path, no wildcards" ?
	? "Written by Rob van der Woude"
	? "http://www.robvanderwoude.com" ?
	Exit 2
EndIf

; Store PATH and PATHEXT in arrays
$pathArray    = Split( "@CurDir;%PATH%", ";", -1 )
$pathExtArray = Split( "%PATHEXT%;.DLL;.SYS;.OCX", ";", -1 )

; Reset search result variable
$found = 0

; Search each directory until one match is found
For Each $i In $pathArray
	If $found = 0
		$pathDir = $i
		; Strip trailing backslash and/or dot
		If Right( $i, 2 ) = "\."
			$pathDir = SubStr( $i, 1, Len( $i ) - 2 )
		Else
			If Right( $i, 1 ) = "\"
				$pathDir = SubStr( $i, 1, Len( $i ) -1 )
			EndIf
		EndIf
		; Try without appending extension first
		If InStr( $search, "." )
			If Exist( $pathDir + "\" + $search )
				$result = $pathDir + "\" + $search
				$found  = 1
			EndIf
		Else
			; Then try all the extensions from PATHEXT
			For Each $j In $pathExtArray
				If Exist( $pathDir + "\" + $search + $j )
					$result = $pathDir + "\" + $search + $j
					$found  = 1
				EndIf
			Next
		EndIf
	EndIf
Next

; Display the result
If $found = 0
	? "-None-" ?
	$ret = 1
Else
	? $result ?
	$ret = 0
EndIf

; Exit with return code
Exit $ret

Back to the top of this page...

 

WHICH.PL, Version 1.01

This Perl version also searches for DLLs, OCXs and SYS files.

#! perl

# Check command line argument(s)
if ( !@ARGV[0] or @ARGV[1] or !( @ARGV[0] =~ m/ˆ[-\w\.]+(\.\w+)?$/ ) ) {
	print "\nWhich.pl,  Version 1.01\n";
	print "Locate the specified program file\n";
	print "Port of Unix' WHICH command\n\n";
	print "Usage:  WHICH.PL  filename[.ext]\n\n";
	print "Where:  \"filename\" is a file name only: no path, no wildcards\n\n";
	print "Written by Rob van der Woude\n";
	print "http://www.robvanderwoude.com\n";
	exit(2);
}

# Store PATH and PATHEXT in arrays
while ( ( $key, $value ) = each %ENV ) {
	if ( uc( $key ) eq "PATH" ) {
		# Current directory must be searched before the PATH
		@path    = ( ".", split( /;+/,$value ) );
	} elsif ( uc( $key ) eq "PATHEXT" ) {
		# Search for "non-executable" program files too
		@pathext = ( split( /;+/,$value ), ".DLL", ".SYS", ".OCX" );
	}
}

# Search code in labelled block, to allow quitting the loop
SEARCH: {
	# Search each directory specified in PATH
	foreach ( @path ) {
		$d = $_;
		# Remove trailing backslash or backslash plus dot
		$d =~ s/ˆ(.*)\\\.?$/\1/;
		# Read the directory (files only)
		opendir( SEARCHDIR, $d ) or die "Cannot open directory $d:\n$!";
		readdir ( SEARCHDIR );
		@files = grep { -f "$d\\$_" } readdir( SEARCHDIR );
		foreach $file ( @files ) {
			# Check for specified file name both with
			# and without each extension from PATHEXT
			foreach $ext ( @pathext ) {
				if ( $file =~ m/ˆ@ARGV[0]($ext)?$/i ) {
					# Display result
					print "\n$d\\$file\n";
					# Close directory handle
					closedir( SEARCHDIR );
					# Abort search at first successful find
					last SEARCH;
				}
			}
		}
		# Close directory handle
		closedir( SEARCHDIR );
	}
	# If you arrived here, the search was unsuccessful
	print "\n-None-\n";
	exit(1);
}

Back to the top of this page...

 

WHICH.PS1, Version 1.00

This PowerShell version also searches for DLLs, OCXs and SYS files.

# Which.ps1,  Version 1.00
# Locate the specified program file
# Port of Unix' WHICH command
#
# Usage:  WHICH.PS1  filename[.ext]
#
# Where:  "filename" is a file name only: no drive or path
#
# Written by Rob van der Woude
# http://www.robvanderwoude.com

param([string] $file=$(throw "Please specify a filename."))
(get-command $file).Definition

Back to the top of this page...

 

WHICH.CMD, Version 3.00 for OS/2

This new WHICH version for OS/2 adds long file name support and the capability to search OS/2's LIBPATH for DLL's. Unlike Windows, OS/2 does not search its PATH for DLL's, but uses LIBPATH. Unfortunately, LIBPATH is not an environment variable, so this Rexx program has to read the LIBPATH line from CONFIG.SYS, which it looks for in the root directory of the boot drive.

/* WHICH, Version 3.00                  */
/* Rexx "port" of UNIX' WHICH command   */
/* that also looks for DLL's in LIBPATH */
/* Written by Rob van der Woude         */

/* Initialize RexxUtil */
if RxFuncQuery( "SysLoadFuncs" ) <> 0 then do
	call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs"
	call SysLoadFuncs
end

/* Parse command line parameters */
parse upper arg params
invalid.0 = 7
invalid.1 = "*"
invalid.2 = "?"
invalid.3 = "/"
invalid.4 = "\"
invalid.5 = ","
invalid.6 = ";"
invalid.7 = ":"
do i = 1 to invalid.0
	if pos( invalid.i, params ) > 0 then call Syntax
end
parse value params with dummy1'"'longfilename'"'dummy2
if longfilename <> "" then do
	if dummy1||dummy2 <> "" then call Syntax
	filename = longfilename
	longname = 1
end
else do
	parse value params with filename dummy
	if filename <> "" then do
		if dummy <> "" then call Syntax
		longname = 0
	end
	else do
		call Syntax
	end
end

/* Check if extension was given */
commandext.0 = 5
commandext.1 = ".BAT"
commandext.2 = ".CMD"
commandext.3 = ".COM"
commandext.4 = ".EXE"
commandext.5 = ".DLL"
addext       = 1
chk4ext      = right( filename, 4 )
do i = 1 to commandext.0
	if chk4ext = commandext.i then addext = 0
end

/* Read PATH from environment */
path = translate( value( "PATH", , "OS2ENVIRONMENT" ) )
if chk4ext = ".DLL" then do
	parse value path with ":\OS2\SYSTEM" -1 bootdrive +2
	configsys = bootdrive||"\CONFIG.SYS"
	call linein configsys, 1, 0
	do until lines( configsys ) = 0
		line = strip( translate( linein( configsys ) ) )
		if left( line, 8 ) = "LIBPATH=" then do
			parse value line with "LIBPATH="path
			leave
		end
	end
end
path.  = ""
path.0 = 1
path.1 = strip( directory( ), "T", "\" )||"\"
do i = 2 by 1 until path = ""
	parse value path with path.i";"path
	if right( path.i, 1 ) <> "\" then path.i = path.i||"\"
	path.0 = i
end

/* Check if file can be found in PATH */
do i = 1 to path.0 until found.0 = 1
	if addext = 0 then do
		file = path.i||filename
		if longname = 1 then do
			file = translate( file, "?", " " )
		end
		call SysFileTree file, "found.", "FO"
		if found.0 = 1 then do
			if longname = 0 then do
				call FileFound file
			end
			else do
				file = translate( translate( file, " ", "?" ) )
				if file = translate( found.1 ) then do
					call FileFound file
				end
			end
		end
	end
	else do j = 1 to commandext.0
		file = path.i||filename||commandext.j
		if longname = 1 then do
			file = translate( file, "?", " " )
		end
		call SysFileTree file, "found.", "FO"
		if found.0 = 1 then do
			if longname = 0 then do
				call FileFound file
			end
			else do
				file = translate( translate( file, " ", "?" ) )
				if file = translate( found.1 ) then do
					call FileFound file
				end
			end
		end
	end
end
say "Not found: "||filename
EXIT 1


FileFound:
	if longname = 1 then do
		say 'Found: "'||arg( 1 )||'"'
	end
	else do
		say "Found: "||arg( 1 )
	end
	EXIT 0
return

Syntax: procedure
	say
	say "WHICH, Version 3.00"
	say "UNIX-like WHICH utility for OS/2 that"
	say "can search for DLL's in LIBPATH as well"
	say "Written by Rob van der Woude"
	say
	say "Usage:  WHICH  program_name"
	say
	say "   or:  WHICH  dll_name.DLL"
	say
	say "You may specify program_name with or without"
	say "extension. program_name as well as dll_name.DLL"
	say "should be specified without a drive or path."
	say
	say "Spaces in long file names are allowed, wildcards"
	say "aren't."
	EXIT 9
return

Back to the top of this page...

 

WHICH.REX, Version 1.00 for Windows

To port WHICH.REX to Regina Rexx for Windows only 3 changes were required:

/* WHICH, Version 1.00 for Windows    */
/* Rexx "port" of UNIX' WHICH command */
/* that also looks for DLL's          */
/* Written by Rob van der Woude       */

/* Initialize RexxUtil */
If RxFuncQuery( "SysLoadFuncs" ) <> 0 Then Do
	Call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs"
	Call SysLoadFuncs
End

/* Display empty line */
Say

/* Parse command line parameters */
Parse Upper Arg params
invalid.0 = 7
invalid.1 = "*"
invalid.2 = "?"
invalid.3 = "/"
invalid.4 = "\"
invalid.5 = ","
invalid.6 = ";"
invalid.7 = ":"
Do i = 1 To invalid.0
	If Pos( invalid.i, params ) > 0 Then Call Syntax
End
Parse Value params With dummy1'"'longfilename'"'dummy2
If longfilename <> "" Then Do
	If dummy1||dummy2 <> "" Then Call Syntax
	filename = longfilename
	longname = 1
End
Else Do
	Parse Value params With filename dummy
	If filename <> "" Then Do
		If dummy <> "" Then Call Syntax
		longname = 0
	End
	Else Do
		Call Syntax
	End
End

/* Check if extension was given */
pathext = Translate( Value( "PATHEXT", , "ENVIRONMENT" ) )
Do i = 1 By 1 Until pathext = ""
	Parse Value pathext With commandext.i";"pathext
	If commandext.i <> "" Then commandext.0 = i
End
i = commandext.0 + 1
commandext.i = ".DLL"
i = commandext.0 + 2
commandext.i = ".SYS"
i = commandext.0 + 3
commandext.i = ".OCX"
commandext.0 = i
addext       = 1
chk4ext      = Right( filename, 4 )
Do i = 1 To commandext.0
	If chk4ext = commandext.i Then addext = 0
End

/* Read PATH from environment */
path = Translate( Value( "PATH", , "ENVIRONMENT" ) )
path.  = ""
path.0 = 1
/* Add current directory as first PATH entry */
path.1 = Strip( Directory( ), "T", "\" )||"\"
Do i = 2 By 1 Until path = ""
	Parse Value path With path.i";"path
	If Right( path.i, 1 ) <> "\" Then path.i = path.i||"\"
	path.0 = i
End

/* Check if file can be found in PATH */
Do i = 1 To path.0 Until found.0 = 1
	If addext = 0 Then Do
		file = path.i||filename
		If longname = 1 Then Do
			file = Translate( file, "?", " " )
		End
		Call SysFileTree file, "found.", "FO"
		If found.0 = 1 Then Do
			If longname = 0 Then Do
				Call FileFound file
			End
			Else Do
				file = Translate( Translate( file, " ", "?" ) )
				If file = Translate( found.1 ) Then Do
					Call FileFound file
				End
			End
		End
	End
	Else Do j = 1 To commandext.0 - 3
		file = path.i||filename||commandext.j
		If longname = 1 Then Do
			file = Translate( file, "?", " " )
		End
		Call SysFileTree file, "found.", "FO"
		If found.0 = 1 Then Do
			If longname = 0 Then Do
				Call FileFound file
			End
			Else Do
				file = Translate( Translate( file, " ", "?" ) )
				If file = Translate( found.1 ) Then Do
					Call FileFound file
				End
			End
		End
	End
End
Say "Not found: "||filename
Exit 1


FileFound:
	If longname = 1 Then Do
		Say 'Found: "'||arg( 1 )||'"'
	End
	Else Do
		Say "Found: "||arg( 1 )
	End
	Exit 0
Return

Syntax: Procedure
	Say
	Say "Which.rex, Version 1.00 for Regina Rexx for Windows"
	Say "UNIX-like WHICH utility for Windows that can search for"
	Say ".DLL, .OCX and .SYS files as well"
	Say
	Say "Usage:    WHICH  program_name"
	Say
	Say 'Where:    "program_name"  is any program name with or without extension,'
	Say "                          but always without drive and/or path."
	Say
	Say "Returns:  The first file with a valid or specified extension found in the PATH."
	Say
	Say "If program_name is specified without extension, all extensions from the PATHEXT"
	Say "environment variable will be searched for."
	Say "Files with .DLL, .OCX or .SYS extension will be ignored unless the extension is"
	Say "specified."
	Say "Spaces in long file names are allowed, wildcards aren't."
	Say
	Say "Written by Rob van der Woude"
	Say "http://www.robvanderwoude.com"
	Exit 9
Return

Back to the top of this page...

 

WHICH.VBS, Version 1.01

This VBScript version is the only version so far that checks for internal commands first, to emulate the behaviour of the command interpreter. The reference list of internal commands is based on the command interpreter specified in the %COMSPEC% environment variable (COMMAND.COM or CMD.EXE).
This script can also be used to search for .DLL, .OCX or .PS1 files ("program" extensions without a file association).
As an added bonus, I added some command line switches to control the output and behaviour of this script. Read the script's on-screen help and/or its source code for details.

Option Explicit

Dim arrInt, arrPath, arrPathExt
Dim blnAll, blnClipboard, blnExtOnly, blnQuiet, blnShort
Dim i, intArgs
Dim objFSO, objIE, wshShell
Dim strComSpec, strIntAll, strIntCmd, strIntCom
Dim strPath, strPathExt, strResult

' Initialize variables
intArgs   = 0
strResult = ""

' Check the command line for exactly 1 argument (the file
' name), which should NOT contain wildcard characters
If WScript.Arguments.Unnamed.Count   <>   1   Then Syntax
If InStr( WScript.Arguments.Unnamed(0), "*" ) Then Syntax
If InStr( WScript.Arguments.Unnamed(0), "?" ) Then Syntax

' Check the command line switches
If WScript.Arguments.Named.Exists( "A" ) Then
    blnAll  = True
    intArgs = intArgs + 1
Else
    blnAll  = False
End If
If WScript.Arguments.Named.Exists( "C" ) Then
    blnClipboard = True
    intArgs      = intArgs + 1
Else
    blnClipboard = False
End If
If WScript.Arguments.Named.Exists( "Q" ) Then
    ' /Q can only be used with /C
    If blnClipboard Then
        blnQuiet = True
        intArgs  = intArgs + 1
    Else
        Syntax
    End If
Else
    blnQuiet = False
End If
If WScript.Arguments.Named.Exists( "S" ) Then
    blnShort = True
    intArgs  = intArgs + 1
Else
    blnShort = False
End If
If WScript.Arguments.Named.Exists( "X" ) Then
    blnExtOnly = True
    intArgs    = intArgs + 1
Else
    blnExtOnly = False
End If

' Check for invalid command line switches
If intArgs <> WScript.Arguments.Named.Count Then Syntax

' Create the required objects
Set objFSO   = CreateObject( "Scripting.FileSystemObject" )
Set wshShell = CreateObject( "Wscript.Shell" )

' Define internal command lists
strIntAll = "BREAK CALL CD CHCP CHDIR CLS COPY DATE DEL DIR ECHO ERASE " _
          & "EXIT FOR GOTO IF MD MKDIR MOVE PATH PAUSE PROMPT RD REM " _
          & "REN RENAME RMDIR SET SHIFT TIME TYPE VER VERIFY VOL "
strIntCmd = "ASSOC COLOR ENDLOCAL FTYPE POPD PUSHD SETLOCAL START TITLE"
strIntCom = "CTTY LFNFOR LH LOADHIGH LOCK TRUENAME UNLOCK"

' Determine the type of command processor
' used: COMMAND.COM or CMD.EXE
strComSpec = UCase( wshShell.ExpandEnvironmentStrings( "%COMSPEC%" ) )
If Right( strComSpec, 12 ) = "\COMMAND.COM" Then
    arrInt = Split( strIntAll & strIntCom )
End If
If Right( strComSpec, 8 ) = "\CMD.EXE" Then
    arrInt = Split( strIntAll & strIntCmd )
End If

' Read the PATH and PATHEXT variables, and store their values in
' arrays; the current directory is prepended to the PATH first
strPath    = wshShell.CurrentDirectory & ";" _
           & wshShell.ExpandEnvironmentStrings( "%PATH%" )
strPathExt = wshShell.ExpandEnvironmentStrings( "%PATHEXT%" )
arrPath    = Split( strPath, ";" )
arrPathExt = Split( strPathExt, ";" )

' Check if the command line argument contains a dot
' which would mean we wouldn't have to use PATHEXT
If InStr( WScript.Arguments.Unnamed(0), "." ) = 0 Then
    ' But first let's check for INTERNAL commands, unless of course, the /X switch was used
    If IsArray( arrInt ) And Not blnExtOnly Then
        For i = 0 To UBound( arrInt )
            If UCase( WScript.Arguments.Unnamed(0) ) = arrInt(i) Then
                strResult = "[" & wshShell.ExpandEnvironmentStrings( "%COMSPEC%" ) _
                          & "]::" & arrInt(i)
                Exit For
            End If
        Next
    End If
    If strResult = "" Then
        ' Use list of valid extensions from PATHEXT if
        ' no extension was specified on the command line
        For i = 0 To UBound( arrPathExt )
            ' Search the PATH
            strResult = strResult _
                      & FindWhich( WScript.Arguments.Unnamed(0) & arrPathExt(i) )
            ' Unless the /A (All) command line switch was
            ' used, abort when the first file is found
            If Not blnAll And strResult <> "" Then
                Exit For
            End If
        Next
    End If
Else
    ' If an extension WAS specified, just search the PATH
    strResult = FindWhich( WScript.Arguments.Unnamed(0) )
End If

' Copy the result to clipboard if the /C command line switch was used
If blnClipboard Then
    Set objIE = CreateObject( "InternetExplorer.Application" )
    objIE.Navigate( "about:blank" )
    objIE.Document.ParentWindow.ClipboardData.SetData "text", strResult
    objIE.Quit
    Set objIE = Nothing
End If

' Display the result, unless the /Q command line switch was used
If Not blnQuiet Then
    WScript.Echo strResult
End If


Function FindWhich( myFile )
    ' This function searches the directories in
    ' the PATH array for the specified file name
    Dim i, objFound, strFound, strFullPath, strTestPath
    strFound = ""
    For i = 0 To UBound( arrPath )
        ' Skip empty directory values, caused by the PATH
        ' variable being terminated with a semicolon
        If arrPath(i) <> "" Then
            ' Build a fully qualified path of the file to test for
            strTestPath = objFSO.BuildPath( arrPath(i), myFile )
            ' Check if that file exists
            If objFSO.FileExists( strTestPath ) Then
                If blnShort Then
                    ' Get the capitalization right
                    strTestPath  = objFSO.GetAbsolutePathName( strTestPath )
                    ' Return the short full path
                    Set objFound = objFSO.GetFile( strTestPath )
                    strFullPath  = objFound.ShortPath
                    Set objFound = Nothing
                Else
                    ' Return the full path with proper capitalization
                    strFullPath = objFSO.GetAbsolutePathName( strTestPath )
                End If
                If blnAll Then
                    ' Append the path of the file found
                    strFound = strFound & ";" _
                             & strFullPath
                Else
                    ' Abort when the first file is found
                    strFound = strFullPath
                    Exit For
                End If
            End If
        End If
    Next
    If blnAll And strFound <> "" Then
        strFound = Replace( Mid( strFound, 2 ), ";", vbCrLf ) & vbCrLf
    End If
    FindWhich = strFound
End Function


Sub Syntax( )
    Dim strMsg
    strMsg = vbCrLf _
           & "Which.vbs,  Version 1.10" & vbCrLf _
           & "Find out which file or internal command is actually executed when you type" _
           & vbCrLf _
           & "a command without its fully qualified path (like UNIX' which command)" _
           & vbCrLf & vbCrLf _
           & "Usage:  WHICH.VBS  filename[.ext]  [ /A ]  [ /C [ /Q ] ]  [/S]  [/X]" _
           & vbCrLf & vbCrLf _
           & "Where:  filename[.ext]  the file name with optional extension to search for;" _
           & vbCrLf _
           & "                        wildcard characters (""*"" and ""?"") are NOT allowed;" _
           & vbCrLf _
           & "                        use the extension to search for .dll, .ocx, .ps1, etc." _
           & vbCrLf _
           & "        /A              list All files found instead of only the first match" _
           & vbCrLf _
           & "                        (ignored if a matching internal command is found)" _
           & vbCrLf _
           & "        /C              copy result to the Clipboard" _
           & vbCrLf _
           & "        /Q              Quiet mode, no screen output (only valid with /C)" _
           & vbCrLf _
           & "        /S              return Short path(s) (8.3 notation)" _
           & vbCrLf _
           & "        /X              eXternal commands only, ignore internal commands" _
           & vbCrLf & vbCrLf _
           & "Written by Rob van der Woude" & vbCrLf _
           & "http://www.robvanderwoude.com" & vbCrLf
    WScript.Echo strMsg
    WScript.Quit 1
End Sub

Back to the top of this page...

 

WHICH.BAT, Version 1.00 SLE for DOS

I added this DOS version just for fun, to show the difference between "real" and "enhanced" DOS versions.
SLE stands for Severely Limited Edition.
It doesn't take an extremely long PATH variable for this batch file to encounter the 127 character limit on command lines, posed by COMMAND.COM.

@ECHO OFF
:: Command line error check:
IF "%1"=="" GOTO Syntax

:: Check PATH length:
SET TEST=
FOR %%A IN (.\;%PATH%) DO SET TEST=OK
CLS
IF NOT "%TEST%"=="OK" GOTO StrLength

:: The actual program:
ECHO.
FOR %%A IN (.\;%PATH%) DO IF EXIST %%A.\%1.BAT TRUENAME %%A.\%1.BAT
FOR %%A IN (.\;%PATH%) DO IF EXIST %%A.\%1.EXE TRUENAME %%A.\%1.EXE
FOR %%A IN (.\;%PATH%) DO IF EXIST %%A.\%1.COM TRUENAME %%A.\%1.COM
FOR %%A IN (.\;%PATH%) DO IF EXIST %%A.\%1     TRUENAME %%A.\%1
GOTO End

:: PATH length error message:
:StrLength
ECHO.
ECHO Sorry, your PATH environment variable is too long to
ECHO be handled by this batch file.
ECHO.
ECHO The 127 character command line limit was exceeded
ECHO when just testing.
GOTO End

:: Help screen:
:Syntax
ECHO.
ECHO WHICH, Version 1.00
ECHO UNIX-like WHICH utility for DOS
ECHO Written by Rob van der Woude
ECHO.
ECHO Usage:  WHICH  program_name
ECHO.
ECHO You may specify program_name with or without extension,
ECHO but without a drive or path.
ECHO Spaces or wildcards aren't allowed either.
ECHO.
ECHO Limitation: This batch file has problems handling long
ECHO             PATH variables; it will say so, however,
ECHO             when it encounters this problem.

:End
ECHO.
SET TEST=

Back to the top of this page...