How to Find Correct Executable with Sys.Which on Windows

How to find correct executable with Sys.which on Windows

I asked a +/- identical question earlier this year over on R-devel. Among the replies was this one, by Henrik Bengtsson, who kindly provided the following useful function:

Sys.which2 <- function(cmd) {
stopifnot(length(cmd) == 1)
if (.Platform$OS.type == "windows") {
suppressWarnings({
pathname <- shell(sprintf("where %s 2> NUL", cmd), intern=TRUE)[1]
})
if (!is.na(pathname)) return(setNames(pathname, cmd))
}
Sys.which(cmd)
}

## Trying out Sys.which & Sys.which2 on my Windows box gives the following:
Sys.which("convert")
# convert
# "C:\\Windows\\system32\\convert.exe"
Sys.which2("convert")
# convert
# "C:\\Program Files\\ImageMagick-6.8.8-Q16\\convert.exe"

I'm really not sure why R-core don't just fix Sys.which() to make it actually portable, but they at least do document root cause of this behavior in ?system (whose functionality is afflicted by the same problem):

The search path for 'command' may be system-dependent: it will
include the R 'bin' directory, the working directory and the
Windows system directories before 'PATH'.

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

Windows Server 2003 and later (i.e. anything after Windows XP 32 bit) provide the where.exe program which does some of what which does, though it matches all types of files, not just executable commands. (It does not match built-in shell commands like cd.) It will even accept wildcards, so where nt* finds all files in your %PATH% and current directory whose names start with nt.

Try where /? for help.

Note that Windows PowerShell defines where as an alias for the Where-Object cmdlet, so if you want where.exe, you need to type the full name instead of omitting the .exe extension. Alternatively, you can set an alias for it:

Set-Alias which where.exe

Update: Using Get-Command (alias: gcm) is recommended since it's native to PS and will get all command types: aliases, cmdlets, executables, and functions. Example:

gcm notepad*

`Sys.which` does not find an executable file in RStudio

So the $PATH value for your shell is different (at start, or via your 'dot'-files) than it is for RStudio. And the result path reveals: /home/$USER/.local/bin is a private path, not a system path.

I think RStudio honors ~/bin so maybe create that and add a softlink.

On the other hand, on my machine (Ubuntu 20.04, R 4.0.2, RStudio 1.4.781) I see

R> system("echo $PATH")
/home/edd/.local/bin:/home/edd/bin:/usr/local/sbin:/usr/local/bin:\
/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:\
/usr/lib/rstudio/bin/postback
R>

and this is not a fluke of system() as Sys.getenv("PATH") shows the same.

Getting the absolute path of the executable, using C#?

MSDN has an article that says to use System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase; if you need the directory, use System.IO.Path.GetDirectoryName on that result.

Or, there's the shorter Application.ExecutablePath which "Gets the path for the executable file that started the application, including the executable name" so that might mean it's slightly less reliable depending on how the application was launched.

Python location of script if run as .exe from different place on Windows

After some testing (thanks buran for his/her guidance), I ended up using this solution:

import sys
import os

if getattr(sys, 'frozen', False):
script_location = sys.executable
else:
script_location = os.path.abspath(__file__)
script_location = os.path.dirname(script_location)

which currently seems to be working both for the .py version and the .exe version of the program build by pyinstaller.

The

sys._MEIPASS

was giving me location in

Appdata\Local\Temp 

which is not what I wanted.

Finding the path of the program that will execute from the command line in Windows

Use the where command. The first result in the list is the one that will execute.


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

According to this blog post, where.exe is included with Windows Server 2003 and later, so this should just work with Vista, Win 7, et al.

On Linux, the equivalent is the which command, e.g. which ssh.

How to check if an executable command exists in R

If it is a command in PATH, then it is actually a file somewhere in the search path.

An easy way is

system("which <command>")  # for unix
system("where <command>") # for windows

If the command exists, then this should show the full path. Otherwise nothing.



Related Topics



Leave a reply



Submit