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