(view source code of which.vbs as plain text)
Option Explicit
Dim arrFound, arrInt, arrPath, arrPathExt, arrTemp
Dim blnAll, blnClipboard, blnExtOnly, blnHasExt, blnQuiet, blnShort, blnVer
Dim i, intArgs, j
Dim objFile, objFSO, objIE, wshShell
Dim strComSpec, strExt, strIntAll, strIntCmd, strIntCom, strPath, strPathExt, strResult, strTime, strVer
' Initialize variables
intArgs = 0
strResult = ""
With WScript.Arguments
' Check the command line for exactly 1 argument (the file
' name), which should NOT contain wildcard characters
If .Unnamed.Count <> 1 Then Syntax
If InStr( .Unnamed(0), "*" ) Then Syntax
If InStr( .Unnamed(0), "?" ) Then Syntax
' Check the command line switches
If .Named.Exists( "A" ) Then
blnAll = True
intArgs = intArgs + 1
Else
blnAll = False
End If
If .Named.Exists( "C" ) Then
blnClipboard = True
intArgs = intArgs + 1
Else
blnClipboard = False
End If
If .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 .Named.Exists( "S" ) Then
blnShort = True
intArgs = intArgs + 1
Else
blnShort = False
End If
If .Named.Exists( "V" ) Then
blnVer = True
intArgs = intArgs + 1
Else
blnVer = False
End If
If .Named.Exists( "X" ) Then
blnExtOnly = True
intArgs = intArgs + 1
Else
blnExtOnly = False
End If
' Check for remaining invalid command line switches
If intArgs <> .Named.Count Then Syntax
End With
' 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
blnHasExt = CBool( InStr( WScript.Arguments.Unnamed(0), "." ) > 0 )
If blnHasExt Then
' If an extension WAS specified, just search the PATH
strExt = Mid( WScript.Arguments.Unnamed(0), InStrRev( WScript.Arguments.Unnamed(0), "." ) )
arrPathExt = Array( strExt )
strResult = FindWhich( WScript.Arguments.Unnamed(0) )
Else
If IsArray( arrInt ) And Not blnExtOnly Then
' Let's check for INTERNAL commands first, unless of course, the /X switch was used
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
strResult = FindWhich( WScript.Arguments.Unnamed(0) )
End If
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
' Return code 1 if not found
WScript.Quit -( strResult = "" )
Function FindWhich( myFile )
' This function searches the directories in the PATH array for the
' specified file name, adding extensions from PATHEXT if required
Dim i, j, 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 Trim( arrPath(i) ) <> "" Then
' Iterate through the array with extensions (if an extension was specified,
' the array will only contain the specified extension, otherwise it will
' contain all extensions in PATHEXT)
For j = 0 To UBound( arrPathExt )
' Build a fully qualified path of the file to test for
strTestPath = objFSO.BuildPath( arrPath(i), objFSO.GetBaseName( myFile ) & arrPathExt(j) )
' Check if that file exists
If objFSO.FileExists( strTestPath ) Then
Set objFound = objFSO.GetFile( strTestPath )
If blnVer Then
strVer = objFSO.GetFileVersion( strTestPath )
If strVer = "" Then
strVer = objFound.DateLastModified
End If
End If
If blnShort Then
' Get the capitalization right
strTestPath = objFSO.GetAbsolutePathName( strTestPath )
' Return the short full path
strFullPath = objFound.ShortPath
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
If blnVer Then strFound = strFound & vbTab & strVer
strFound = strFound & ";"
Else
' Abort when the first file is found
strFound = strFullPath
If blnVer Then strFound = strFound & vbTab & strVer
Exit For
End If
Set objFound = Nothing
' Unless the /A (All) command line switch was used, abort inner loop after the first file is found
If strFound <> "" And Not blnAll Then Exit For
End If
Next
End If
' Unless the /A (All) command line switch was used, abort outer loop after the first file is found
If strFound <> "" And Not blnAll Then Exit For
Next
If strFound <> "" Then
arrFound = Split( strFound, ";" )
strFound = Join( arrFound, vbCrLf )
End If
FindWhich = strFound
End Function
Sub Syntax( )
Dim strMsg
strMsg = vbCrLf _
& "Which.vbs, Version 1.20" & vbCrLf _
& "Find out which file or internal command is actually executed when you type" _
& vbCrLf _
& "a command without its fully qualified path (like UNIX command, but extended)" _
& vbCrLf & vbCrLf _
& "Usage: WHICH.VBS filename[.ext] [ /A ] [ /C [ /Q ] ] [/S] [/V] [/X]" _
& vbCrLf & vbCrLf _
& "Where: filename[.ext] file name (with optional extension) or internal command" _
& vbCrLf _
& " to search for; wildcards (""*"" and ""?"") are not allowed;" _
& vbCrLf _
& " use the extension to search for .dll, .ocx, .ps1, etc." _
& vbCrLf _
& " /A list All matches, not just the first match" _
& 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 _
& " /V show Version number" _
& vbCrLf _
& " /X eXternal commands only, ignore internal commands" _
& vbCrLf & vbCrLf _
& "Notes: /A and /V switches will be ignored for internal commands" _
& vbCrLf _
& " /V will display file timestamp for non-executables" _
& vbCrLf & vbCrLf _
& "Written by Rob van der Woude" & vbCrLf _
& "http://www.robvanderwoude.com" & vbCrLf
WScript.Echo strMsg
WScript.Quit 1
End Sub
page last modified: 2024-04-16; loaded in 0.0072 seconds