Is there an equivalent of 'which' on the Windows command line?
Asked Answered
S

27

2835

As I sometimes have path problems, where one of my own cmd scripts is hidden (shadowed) by another program (earlier on the path), I would like to be able to find the full path to a program on the Windows command line, given just its name.

Is there an equivalent to the UNIX command 'which'?

On UNIX, which command prints the full path of the given command to easily find and repair these shadowing problems.

Scansion answered 20/11, 2008 at 4:19 Comment(9)
What does "which" do on Unix?Weigand
Foredecker: "which" searches the PATH for the executable that will be run if you type a command at the shell prompt.Voyage
for example, if you have 5 versions of Java installed and you don't know which one is being used you can type "which java" and it gives you the PATH to the binaryNarration
@Foredecker, MR says it's "where" in Win2k3 but Win2k3 wasn't part of the question. If "where" isn't in the other Windows versions, other answers are also valid. IMNSHO, the answer that works on all Windows versions is the best. Also, the other answers aren't wrong, just different ways of doing it.Zanthoxylum
I know this question arose before SuperUser, but it probably belongs there.Flipflop
You can a batch file having only 90 bytes from here: blogs.msdn.com/b/oldnewthing/archive/2005/01/20/357225.aspx Or run a C# Program - a link is placed on the website above.Pairs
This was asked in other threads: [Equivalent of *Nix 'which' command in Powershell?][1] [Powershell equivalent to unix which command?][2] [1]: #64305 [2]: superuser.com/questions/34492/…Appeal
There is no which command in standard Unix. The POSIX utility is type. The C Shell has a which command, and some systems have it as an external executable. For instance, on Debian Linux, which comes from a package called debutils. This external which does not "see" shell built-ins, aliases or functions. type does; Bash's type has an option to suppress that and just do a path lookup.Guncotton
To illustrate @kaz' point, compare the outputs of which -a pwd versus type -a pwdEluviation
L
3002

I suggest you use Windows PowerShell's Get-Command cmdlet, as described in another answer to this question by Marawan Mamdouh.

If you're like me and don't use PowerShell, use Windows' where.exe program. Like Unix which, it shows the full path that would match the filename-only command you type:

C:\> where edit
C:\Windows\System32\edit.com

Unlike which, where.exe can show all the paths that match the given filename, though only the first one shown would normally be used when launching a program:

C:\> where notepad
C:\Windows\System32\notepad.exe
C:\Windows\notepad.exe

where.exe tries to follow the Windows command shell CMD.EXE's rules for what file names and paths work as commands. That includes the %PATHEXT% environment variable and the ability to open non-program data files using their filenames with extensions:

C:\> set pathext
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

C:\> where Enterprise.xml slmgr
C:\Windows\Enterprise.xml
C:\Windows\System32\slmgr.vbs

where.exe will even accept wildcards, so where nt*.exe finds all files in your %PATH% and current directory whose names start with nt and end with .exe:

C:\> where nt*.exe
C:\Windows\System32\ntoskrnl.exe
C:\Windows\System32\ntprint.exe
C:\Windows\System32\ntvdm.exe

Check the online docs for where.exe or run where.exe /? for more help.


Notes:

  • When using PowerShell, run where.exe as where.exe, never where. Plain where in PowerShell is an alias for the Where-Object cmdlet, which does something very different from where.exe / which.
  • where.exe is available in Windows Server 2003 and later. Sorry if you're still on Windows XP.
Limnetic answered 20/11, 2008 at 5:52 Comment(12)
No, because grep examines the contents of its input, which you have to give explicitly. which and where.exe only look at the names of the files in a set of directories set in the PATH environment variables.Limnetic
Warning: "where" won't work on quoted paths, be sure your %path% doesn't contain any.Silkstocking
Remember that where.exe is not a shell builtin, you need to have %windir%\system32 on your %PATH% - which may not be the case, as using where suggests that you may be working on problems with your path!Multicolor
Didn't work in CMD on Server 2016 without typing where.exeHeadon
Works in Windows 10 too.Terminable
Just to be explicit: where.exe may return multiple values, in which case the first/top most one will be invoked. C:\Windows\System32> where.exe sqlcmd.exe c:\Program Files\Microsoft SQL Server\90\Tools\Binn\SQLCMD.EXE C:\Program Files\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn\SQLCMD.EXESlung
Took this a step further and made a function to search path and program files/windows etc. Can easily be adapter further. See https://mcmap.net/q/40447/-is-there-an-equivalent-of-39-which-39-on-the-windows-command-lineRoyall
re: where.exe may return multiple values But NOT necessarily in the directory order in your echo %PATH% environment variable. On Windows there is both a user level PATH variable and a system level PATH variable. echo %PATH% displays the system variable, but which.exe uses the user level variable first. Surprise!Prolocutor
Server 2012 R2 PSVersion 4.0 Get-Command is returning nothing while where.exe returns the proper list with the version of the target .exe that gets run when called unqualified at the top of the list.Branen
@Headon that's because where is an alias to Where-Object in PowerShell, so to call the executable you have to explicitly specify the file. But don't use where.exe in PowerShell, just use gcm which is far betterKiruna
@MichaelRatanapintha Perhaps add Set-Alias which gcmSitka
The previous set-alias part of the answer wasn't added by me, and I don't necessarily agree with it. Let me revise this answer more thoroughly...Limnetic
Z
319

While later versions of Windows have a where command, you can also do this with Windows XP by using the environment variable modifiers, as follows:

c:\> for %i in (cmd.exe) do @echo.   %~$PATH:i
   C:\WINDOWS\system32\cmd.exe

c:\> for %i in (python.exe) do @echo.   %~$PATH:i
   C:\Python25\python.exe

You don't need any extra tools and it's not limited to PATH since you can substitute any environment variable (in the path format, of course) that you wish to use.


And, if you want one that can handle all the extensions in PATHEXT (as Windows itself does), this one does the trick:

@echo off
setlocal enableextensions enabledelayedexpansion

:: Needs an argument.

if "x%1"=="x" (
    echo Usage: which ^<progName^>
    goto :end
)

:: First try the unadorned filenmame.

set fullspec=
call :find_it %1

:: Then try all adorned filenames in order.

set mypathext=!pathext!
:loop1
    :: Stop if found or out of extensions.

    if "x!mypathext!"=="x" goto :loop1end

    :: Get the next extension and try it.

    for /f "delims=;" %%j in ("!mypathext!") do set myext=%%j
    call :find_it %1!myext!

:: Remove the extension (not overly efficient but it works).

:loop2
    if not "x!myext!"=="x" (
        set myext=!myext:~1!
        set mypathext=!mypathext:~1!
        goto :loop2
    )
    if not "x!mypathext!"=="x" set mypathext=!mypathext:~1!

    goto :loop1
:loop1end

:end
endlocal
goto :eof

:: Function to find and print a file in the path.

:find_it
    for %%i in (%1) do set fullspec=%%~$PATH:i
    if not "x!fullspec!"=="x" @echo.   !fullspec!
    goto :eof

It actually returns all possibilities but you can tweak it quite easily for specific search rules.

Zanthoxylum answered 20/11, 2008 at 5:48 Comment(7)
Hey, I wish I had learned that! Too bad it doesn't work with MS-DOS or Win9x (that is, with command.com). (Raymond Chen has a more "elaborate" version you can turn into a batch file: blogs.msdn.com/oldnewthing/archive/2005/01/20/357225.aspx )Limnetic
@Michael, if you're still using DOS or Win95, finding executables on the path are the least of your problems :-)Zanthoxylum
windows recognizes more than .exe as executable. Last time I coded a which back in W95/DOS days amdittedly, the search order was - current dir, then each path dir, for cmd.com, then cmd.exe, then cmd.bat So, even cmd.bat in current dir is executed befroe cmd.exe soemwhere in pathMozambique
@mawg, the original was for where you know the extension since it mirrors which under UNIX (where that extension-adding trickery doesn't occur). I've now added one which can do what you wish but it's no longer a simple command so much as a script. It first tries the unadorned command then each of the extension ones. Hope that helps. You can tweak it to your needs as you see fit (if you want the same search order as with Windows for example - this one shows all possibilities).Zanthoxylum
To turn this into a batch script, create a file called "which.bat": @echo off for %%i in (%1) do @echo. %%~$PATH:%i To add it to an alias.bat script that you load everytime you run cmd.exe (put the above script in a new directory called C:\usr\aliases): DOSKEY which=C:\usr\aliases\which.bat $* Then you can make a script to launch cmd.exe with the alias.bat file: cmd.exe /K E:\usr\aliases\alias.batAutoxidation
worth noting, The example of for %i in (_____) do @echo. %~$PATH:i will find any extension not just exe. It works for file a.a or youtube-dl.py when that is in the path. But it is funny if you put a directory in there, it outputs it even if it's not in the path e.g. for %i in (%TEMP%) do @echo. %~$PATH:iKutch
Thank you I am working on a Windows 7 with no where command, and that does the the jobFlynn
G
249

Under PowerShell, Get-Command will find executables anywhere in $Env:PATH.

$ Get-Command eventvwr

CommandType   Name          Definition
-----------   ----          ----------
Application   eventvwr.exe  c:\windows\system32\eventvwr.exe
Application   eventvwr.msc  c:\windows\system32\eventvwr.msc

And since powershell let's you define aliases, which can be defined like so.

$ sal which gcm   # short form of `Set-Alias which Get-Command`
$ which foo
...

PowerShell commands are not just executable files (.exe, .ps1, etc). They can also be cmdlets, functions, aliases, custom executable suffixes set in $Env:PATHEXT, etc. Get-Command is able to find and list all of these commands (quite akin to Bash's type -a foo). This alone makes it better than where.exe, which.exe, etc which are typically limited to finding just executables.

Finding executables using only part of the name

$ gcm *disk*

CommandType     Name                             Version    Source
-----------     ----                             -------    ------
Alias           Disable-PhysicalDiskIndication   2.0.0.0    Storage
Alias           Enable-PhysicalDiskIndication    2.0.0.0    Storage
Function        Add-PhysicalDisk                 2.0.0.0    Storage
Function        Add-VirtualDiskToMaskingSet      2.0.0.0    Storage
Function        Clear-Disk                       2.0.0.0    Storage
Cmdlet          Get-PmemDisk                     1.0.0.0    PersistentMemory
Cmdlet          New-PmemDisk                     1.0.0.0    PersistentMemory
Cmdlet          Remove-PmemDisk                  1.0.0.0    PersistentMemory
Application     diskmgmt.msc                     0.0.0.0    C:\WINDOWS\system32\diskmgmt.msc
Application     diskpart.exe                     10.0.17... C:\WINDOWS\system32\diskpart.exe
Application     diskperf.exe                     10.0.17... C:\WINDOWS\system32\diskperf.exe
Application     diskraid.exe                     10.0.17... C:\WINDOWS\system32\diskraid.exe
...

Finding custom executables

Unlike UNIX, where executables are files with the executable (+x) bit set, executables on windows are files present in one of the directories specified in the $PATH env. variable whose filename suffixes are named in the $PATHEXT env. variable (defaults to .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL).

As Get-Command also honours this env. variable, it can be extended to list custom executables. e.g.

$ $Env:PATHEXT="$Env:PATHEXT;.dll;.ps1;.psm1;.py"     # temporary assignment, only for this shell's process

$ gcm user32,kernel32,*WASM*,*http*py

CommandType     Name                        Version    Source
-----------     ----                        -------    ------
ExternalScript  Invoke-WASMProfiler.ps1                C:\WINDOWS\System32\WindowsPowerShell\v1.0\Invoke-WASMProfiler.ps1
Application     http-server.py              0.0.0.0    C:\Users\ME\AppData\Local\Microsoft\WindowsApps\http-server.py
Application     kernel32.dll                10.0.17... C:\WINDOWS\system32\kernel32.dll
Application     user32.dll                  10.0.17... C:\WINDOWS\system32\user32.dll

See Get-Command for more options and examples.

Goodish answered 26/11, 2014 at 2:7 Comment(3)
It finds much more than just executables. It also catches command filesRann
@TheIncorrigible1 - if you mean command files such as batch files (.BAT, .CMD, etc), they are considered executable because their extensions are named in the PATHEXT variable (which by default is PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL). Other executable types (e.g. .py, .rb, etc) can be added by adding the file extension in and creating an executable association with assoc/ftype - e.g. docs.python.org/3.3/using/…Goodish
This should honestly be selected as the best answer now that it is 2020, since the original answer was posted back in 2008. Times have changed. PowerShell is the way, especially being that this answer is now cross-platform for wherever PowerShell exists.Parenthesis
R
70

In Windows PowerShell:

set-alias which where.exe
Roydd answered 30/11, 2012 at 23:0 Comment(0)
D
45

If you have PowerShell installed (which I recommend), you can use the following command as a rough equivalent (substitute programName for your executable's name):

($Env:Path).Split(";") | Get-ChildItem -filter programName*

More is here: My Manwich! PowerShell Which

Destroy answered 20/11, 2008 at 5:16 Comment(5)
I was looking for this exact pithy powershell command. I had been using where.exe but having to mess around with the error code on top of parsing its output is far inferior to a native powershell solution. Thanks!Servia
But ($Env:Path).Split(";") | Get-ChildItem -filter programName* is so easy to type... ;-)Internalize
This also fails if you have a variable in your path that is normally resolved by the system (aka %JAVA_HOME%).Divided
I cannot get which.exe to work, I tried this and it worked.Chieftain
The gcm answer would be far better use of PowerShell today: https://mcmap.net/q/40447/-is-there-an-equivalent-of-39-which-39-on-the-windows-command-lineParenthesis
R
39

The GnuWin32 tools have which, along with a whole slew of other Unix tools.

Retardment answered 20/11, 2008 at 6:44 Comment(0)
B
32

In Windows CMD which calls where:

$ where php
C:\Program Files\PHP\php.exe
Bound answered 1/4, 2016 at 12:2 Comment(3)
Where will list out all the available resources. For me, I used where pip and I got the three results. I am not sure which one is the executed one.Quinn
Your answer is not essentially different from the accepted answer and not very useful since it does not add any new value or information. Please avoid writing duplicate answers, either edit your answer to add value or delete it altogether, this will ensure all questions and answers on the site remain useful not scattered/duplicated.Bucher
@Tekson, the first one in the list is the one that will be executed.Whaleback
F
18

Cygwin is a solution. If you don't mind using a third-party solution, then Cygwin is the way to go.

Cygwin gives you the comfort of *nix in the Windows environment (and you can use it in your Windows command shell, or use a *nix shell of your choice). It gives you a whole host of *nix commands (like which) for Windows, and you can just include that directory in your PATH.

Flipflop answered 12/10, 2010 at 17:2 Comment(3)
GnuWin32 mentioned earlier by Ferruccio is much better in this case as you can have native where executable alone.Lubow
GnuWin32 is great, and I use it, but if you want this functionality without installing the GnuWin32 tools where.exe seems like the right call. Although, I do put the GnuWin32 tools in a \bin$ share on our network so that I can use them from workstations (and in batch files) that don't have them installed locally.Internalize
When we talk about Cygwin usage in Windows, I prefer: cygpath -w "`which <appname>`"Meilen
H
14

In PowerShell, it is gcm, which gives formatted information about other commands. If you want to retrieve only path to executable, use .Source.

For instance: gcm git or (gcm git).Source

Tidbits:

Holocrine answered 11/9, 2015 at 11:32 Comment(0)
E
12

I have a function in my PowerShell profile named 'which'

function which {
    get-command $args[0]| format-list
}

Here's what the output looks like:

PS C:\Users\fez> which python


Name            : python.exe
CommandType     : Application
Definition      : C:\Python27\python.exe
Extension       : .exe
Path            : C:\Python27\python.exe
FileVersionInfo : File:             C:\Python27\python.exe
                  InternalName:
                  OriginalFilename:
                  FileVersion:
                  FileDescription:
                  Product:
                  ProductVersion:
                  Debug:            False
                  Patched:          False
                  PreRelease:       False
                  PrivateBuild:     False
                  SpecialBuild:     False
                  Language:
Enplane answered 31/7, 2015 at 8:59 Comment(1)
None of the other solutions worked for me but > get-command app.exe | format-list worked perfectly!Platinocyanide
L
11

Go get unxutils from here: http://sourceforge.net/projects/unxutils/

gold on windows platforms, puts all the nice unix utilities on a standard windows DOS. Been using it for years.

It has a 'which' included. Note that it's case sensitive though.

NB: to install it explode the zip somewhere and add ...\UnxUtils\usr\local\wbin\ to your system path env variable.

Lacerta answered 26/3, 2010 at 0:8 Comment(3)
it is not case sensitive, also i have to say which java.exe instead of which java - windows 7Shepley
It has a couple of frustrations though having to do with newlines; grep for example won't match EOL without you putting in a . for the \r. It's a 99% solution though for sure!Reinstate
Yes, it is not case sensitive, however by default file names in Windows are not case sensitive either.Barron
M
10

If you can find a free Pascal compiler, you can compile this. At least it works and shows the algorithm necessary.

program Whence (input, output);
  Uses Dos, my_funk;
  Const program_version = '1.00';
        program_date    = '17 March 1994';
  VAR   path_str          : string;
        command_name      : NameStr;
        command_extension : ExtStr;
        command_directory : DirStr;
        search_dir        : DirStr;
        result            : DirStr;


  procedure Check_for (file_name : string);
    { Check existence of the passed parameter. If exists, then state so   }
    { and exit.                                                           }
  begin
    if Fsearch(file_name, '') <> '' then
    begin
      WriteLn('DOS command = ', Fexpand(file_name));
      Halt(0);    { structured ? whaddayamean structured ? }
    end;
  end;

  function Get_next_dir : DirStr;
    { Returns the next directory from the path variable, truncating the   }
    { variable every time. Implicit input (but not passed as parameter)   }
    { is, therefore, path_str                                             }
    var  semic_pos : Byte;

  begin
      semic_pos := Pos(';', path_str);
      if (semic_pos = 0) then
      begin
        Get_next_dir := '';
        Exit;
      end;

      result := Copy(Path_str, 1, (semic_pos - 1));  { return result   }
      { Hmm! although *I* never reference a Root drive (my directory tree) }
      { is 1/2 way structured), some network logon software which I run    }
      { does (it adds Z:\ to the path). This means that I have to allow    }
      { path entries with & without a terminating backslash. I'll delete   }
      { anysuch here since I always add one in the main program below.     }
      if (Copy(result, (Length(result)), 1) = '\') then
         Delete(result, Length(result), 1);

      path_str := Copy(path_str,(semic_pos + 1),
                       (length(path_str) - semic_pos));
      Get_next_dir := result;
  end;  { Of function get_next_dir }

begin
  { The following is a kludge which makes the function Get_next_dir easier  }
  { to implement. By appending a semi-colon to the end of the path         }
  { Get_next_dir doesn't need to handle the special case of the last entry }
  { which normally doesn't have a semic afterwards. It may be a kludge,    }
  { but it's a documented kludge (you might even call it a refinement).    }
  path_str := GetEnv('Path') + ';';

  if (paramCount = 0) then
  begin
    WriteLn('Whence: V', program_version, ' from ', program_date);
    Writeln;
    WriteLn('Usage: WHENCE command[.extension]');
    WriteLn;
    WriteLn('Whence is a ''find file''type utility witha difference');
    Writeln('There are are already more than enough of those :-)');
    Write  ('Use Whence when you''re not sure where a command which you ');
    WriteLn('want to invoke');
    WriteLn('actually resides.');
    Write  ('If you intend to invoke the command with an extension e.g ');
    Writeln('"my_cmd.exe param"');
    Write  ('then invoke Whence with the same extension e.g ');
    WriteLn('"Whence my_cmd.exe"');
    Write  ('otherwise a simple "Whence my_cmd" will suffice; Whence will ');
    Write  ('then search the current directory and each directory in the ');
    Write  ('for My_cmd.com, then My_cmd.exe and lastly for my_cmd.bat, ');
    Write  ('just as DOS does');
    Halt(0);
  end;

  Fsplit(paramStr(1), command_directory, command_name, command_extension);
  if (command_directory <> '') then
  begin
WriteLn('directory detected *', command_directory, '*');
    Halt(0);
  end;

  if (command_extension <> '') then
  begin
    path_str := Fsearch(paramstr(1), '');    { Current directory }
    if   (path_str <> '') then WriteLn('Dos command = "', Fexpand(path_str), '"')
    else
    begin
      path_str := Fsearch(paramstr(1), GetEnv('path'));
      if (path_str <> '') then WriteLn('Dos command = "', Fexpand(path_str), '"')
                          else Writeln('command not found in path.');
    end;
  end
  else
  begin
    { O.K, the way it works, DOS looks for a command firstly in the current  }
    { directory, then in each directory in the Path. If no extension is      }
    { given and several commands of the same name exist, then .COM has       }
    { priority over .EXE, has priority over .BAT                             }

    Check_for(paramstr(1) + '.com');     { won't return if file is found }
    Check_for(paramstr(1) + '.exe');
    Check_for(paramstr(1) + '.bat');

    { Not in current directory, search through path ... }

    search_dir := Get_next_dir;

    while (search_dir <> '') do
    begin
       Check_for(search_dir + '\' + paramstr(1) + '.com');
       Check_for(search_dir + '\' + paramstr(1) + '.exe');
       Check_for(search_dir + '\' + paramstr(1) + '.bat');
       search_dir := Get_next_dir;
    end;

    WriteLn('DOS command not found: ', paramstr(1));
  end;
end.
Mozambique answered 26/3, 2010 at 0:50 Comment(10)
Wow, there are people still using Pascal? :-)Zanthoxylum
I imagine that there are. But not me. Did you see the line program_date = '17 March 1994';Mozambique
The unit my_funk; is unecessary. Thanks for posting a Pascal program, reminds me of my youth! It is such a pity that Pascal did not evolve.Singletary
Oh, but it did. It is now object oriented, for instance. There is a great free, cross-platform, implementation and IDE at lazarus-ide.org And a direct descendant of Borland still lives in Delphi at embarcadero.com/products/delphi which is very expensive (imo) at $299 for the starter edition and $1k for the "usable" edition. However, it is cross platform - windows, iOs, Mac, Android. Get a trial edition or use Lazarus and feel 20 years younger ,-)Mozambique
@yannis "such a pity that Pascal did not evolve" ... apart from 'Turbo Pascal' Anders going on to design C# you mean?Morocco
Or Delphi, or Lazarus? A tiny thing like object orientation does not count as evolution?Mozambique
@Mozambique Delphi was the right way to go. After version 6 and when all the Borland guys fled to Microsoft it put a lot of people off, including myself.Singletary
And now it costs a minimum $1k (!) unless you buy the $299 starter version, which is very limited (last starter I bought had no 64-bit code generation and, even worse for me, no database access). Lazarus is great, but a major plus for Delphi are the thousands of (free) VCL components.Mozambique
As of now (early 2018), they must have realized that they are losing custom, and the starter edition is now free (until you earn US $1k from it). It's only 32 bit, but there are free solutions to the restrictions. Either that, or Lazarus look goodMozambique
And, now, in December 2020, it has a community edition - go nostalgisize yourselfMozambique
M
8

Not in stock Windows but it is provided by Services for Unix and there are several simple batch scripts floating around that accomplish the same thing such this this one.

Melvin answered 20/11, 2008 at 4:28 Comment(1)
Except that the command you link only outputs the PATH variable and does not even check if the file is found there.Divagate
M
8

You can first install Git from Downloading Git, and then open Git Bash and type:

which app-name
Miso answered 2/8, 2017 at 6:40 Comment(0)
O
7

The best version of this I've found on Windows is Joseph Newcomer's "whereis" utility, which is available (with source) from his site.

The article about the development of "whereis" is worth reading.

Orgeat answered 20/11, 2008 at 5:9 Comment(1)
Late comment: whereis has problems to find 64-bit executables under Win 7 64-bit.Chilt
J
6

None of the Win32 ports of Unix which that I could find on the Internet are satistactory, because they all have one or more of these shortcomings:

  • No support for Windows PATHEXT variable. (Which defines the list of extensions implicitely added to each command before scanning the path, and in which order.) (I use a lot of tcl scripts, and no publicly available which tool could find them.)
  • No support for cmd.exe code pages, which makes them display paths with non-ascii characters incorrectly. (I'm very sensitive to that, with the ç in my first name :-))
  • No support for the distinct search rules in cmd.exe and the PowerShell command line. (No publicly available tool will find .ps1 scripts in a PowerShell window, but not in a cmd window!)

So I eventually wrote my own which, that suports all the above correctly.

Available there: http://jf.larvoire.free.fr/progs/which.exe

Johannesburg answered 18/12, 2014 at 13:29 Comment(1)
FYI I've open-sourced my which.exe tool mentioned above, and many others, on github.com/JFLarvoire/SysToolsLib. You may get the latest version there, report issues, etc.Hake
E
6

This batch file uses CMD variable handling to find the command that would be executed in the path. Note: that the current directory is always done before the path) and depending on which API call is used other locations are searched before/after the path.

@echo off
echo. 
echo PathFind - Finds the first file in in a path
echo ======== = ===== === ===== ==== == == = ====
echo. 
echo Searching for %1 in %path%
echo. 
set a=%~$PATH:1
If "%a%"=="" (Echo %1 not found) else (echo %1 found at %a%)

See set /? for help.

Employer answered 25/9, 2016 at 1:45 Comment(0)
S
6

I am using GOW (GNU on Windows) which is a light version of Cygwin. You can grab it from GitHub here.

GOW (GNU on Windows) is the lightweight alternative to Cygwin. It uses a convenient Windows installer that installs about 130 extremely useful open source UNIX applications compiled as native win32 binaries. It is designed to be as small as possible, about 10 MB, as opposed to Cygwin which can run well over 100 MB depending upon options. - About Description(Brent R. Matzelle)

A screenshot of a list of commands included in GOW:

Enter image description here

Sancho answered 13/12, 2017 at 8:58 Comment(0)
K
5

I have created tool similar to Ned Batchelder:

Searching .dll and .exe files in PATH

While my tool is primarly for searching of various dll versions it shows more info (date, size, version) but it do not use PATHEXT (I hope to update my tool soon).

Kimmy answered 20/11, 2008 at 9:39 Comment(0)
D
5

Just have to post this Windows' one liner batch file:

C:>type wh.cmd
@for %%f in (%*) do for %%e in (%PATHEXT% .dll .lnk) do for %%b in (%%f%%e) do for %%d in (%PATH%) do if exist %%d\%%b echo %%d\%%b

A test:

C:>wh ssh
C:\cygwin64\bin\ssh.EXE
C:\Windows\System32\OpenSSH\\ssh.EXE

Not quite a one-liner if you wrap the code in setlocal enableextensions and endlocal.

Distended answered 8/10, 2019 at 11:37 Comment(1)
Would prefer that in multiple lines so I could understand it. ;-)Tereasaterebene
K
4

For you Windows XP users (who have no where command built-in), I have written a "where like" command as a rubygem called whichr.

To install it, install Ruby.

Then

gem install whichr

Run it like:

C:> whichr cmd_here

Kenton answered 2/9, 2015 at 14:59 Comment(3)
I suspect that you're being downvoted because you're suggesting doing anything on Windows XP.Snowfield
Didn't downvote but installing Ruby to implement a trivial command is a hard sell as well. There is a for loop above that could be put into a batch script.Tereasaterebene
Does it print the opening lines to the theme song for The Witcher if you run it in verbose mode? ;)Aureolin
K
3

TCC and TCC/LE from JPSoft are CMD.EXE replacements that add significant functionality. Relevant to the OP's question, which is a builtin command for TCC family command processors.

Kandis answered 9/2, 2017 at 23:31 Comment(0)
A
2

I have used the which module from npm for quite a while, and it works very well: https://www.npmjs.com/package/which It is a great multi platform alternative.

Now I switched to the which that comes with Git. Just add to your path the /usr/bin path from Git, which is usually at C:\Program Files\Git\usr\bin\which.exe. The which binary will be at C:\Program Files\Git\usr\bin\which.exe. It is faster and also works as expected.

Algae answered 1/6, 2018 at 2:2 Comment(0)
P
2

If you want to find the source of command, you can use the Get-Command cmdlet or its alias gcm.

Example Usage:

you can use Get-Command or its alias gcm directly. For example:

Get-Command python, poetry

or

gcm python, poetry

you will get some thing like this

CommandType     Name             Version    Source
-----------     ----             -------    ------
Application     python.exe       3.12.15... C:\Program Files\Python312\python.exe
Application     poetry.exe       0.0.0.0    C:\Users\xxx\AppData\Roaming\Python\Scripts\poetry.exe

However, if you want to get only to source direct you can use the custom function Get-CommandSource provided below.

function Get-PackageSource {
    param (
        [string[]]$Packages
    )

    (Get-Command $Packages).Source
}

# Alias for Get-CommandSource
New-Alias -Name gcms -Value Get-CommandSource

Example Usage:

If you have a list of commands and want to quickly identify their sources, you can use the Get-CommandSource function or its alias gcms. For example:

gcms python, poetry
python: C:\Program Files\Python312\python.exe
poetry: C:\Users\xxx\AppData\Roaming\Python\Scripts\poetry.exe

Additional Note:

To ensure that the gcms alias is available in future PowerShell sessions, add the alias to the PowerShell profile

notepad.exe $PROFILE
Progenitive answered 15/10, 2023 at 3:43 Comment(1)
Upvoted. works on powershell but not on cmdFoldboat
J
1

try this

set a=%~$dir:1
If "%for%"=="" (Echo %1 not found) else (echo %1 found at %a%)
Jacki answered 3/5, 2019 at 13:0 Comment(0)
O
0

It is possible to download all of the UNIX commands compiled for Windows, including which from this GitHub repository: https://github.com/George-Ogden/UNIX

Offwhite answered 4/7, 2020 at 17:44 Comment(1)
"All of" is not well-defined; and indeed, which is not strictly speaking one of them, by any reasonably well-specified definition of "all of".Collage
R
-1

Here is a function which I made to find executable similar to the Unix command 'WHICH`

app_path_func.cmd:

@ECHO OFF
CLS

FOR /F "skip=2 tokens=1,2* USEBACKQ" %%N IN (`reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\%~1" /t REG_SZ  /v "Path"`) DO (
 IF /I "%%N" == "Path" (
  SET wherepath=%%P%~1
  GoTo Found
 )
)

FOR /F "tokens=* USEBACKQ" %%F IN (`where.exe %~1`) DO (
 SET wherepath=%%F
 GoTo Found
)

FOR /F "tokens=* USEBACKQ" %%F IN (`where.exe /R "%PROGRAMFILES%" %~1`) DO (
 SET wherepath=%%F
 GoTo Found
)

FOR /F "tokens=* USEBACKQ" %%F IN (`where.exe /R "%PROGRAMFILES(x86)%" %~1`) DO (
 SET wherepath=%%F
 GoTo Found
)

FOR /F "tokens=* USEBACKQ" %%F IN (`where.exe /R "%WINDIR%" %~1`) DO (
 SET wherepath=%%F
 GoTo Found
)

:Found
SET %2=%wherepath%
:End

Test:

@ECHO OFF
CLS

CALL "app_path_func.cmd" WINWORD.EXE PROGPATH
ECHO %PROGPATH%

PAUSE

Result:

C:\Program Files (x86)\Microsoft Office\Office15\
Press any key to continue . . .

https://www.freesoftwareservers.com/display/FREES/Find+Executable+via+Batch+-+Microsoft+Office+Example+-+WINWORD+-+Find+Microsoft+Office+Path

Royall answered 5/8, 2020 at 3:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.