Karsten W.
Karsten W.

Reputation: 18500

Find Rscript.exe on Windows

I would like to execute Rscript on a windows computer. For this, I need to find the exact location of Rscript, since it is not on %PATH%. Searching stackoverflow, I found this approach

where /r "c:\Program Files" Rscript.exe

which produces three lines:

c:\Program Files\R\R-3.6.2\bin\Rscript.exe
c:\Program Files\R\R-3.6.2\bin\i386\Rscript.exe
c:\Program Files\R\R-3.6.2\bin\x64\Rscript.exe

Now I do not know how to proceed. How can I assign one of the three lines to a (local) environment variable in windows cmd? Ideally, it would be the first or third line, i.e. the x64 rscript.exe.

Another approach I found on SO is like this:

set "src=c:\Program Files"
set "search=Rscript.exe"

for /r "%src%" %%F in (*%search%*) do (
  set "full=%%~fF"
  set "name=%%~nxF"
  echo %full%
)

but somehow nothing gets assigned to %full%.

Since I would like to run the batch file on more than one computer, I would like to avoid doing extra configuration on these computers (like setting PATH or R_HOME or assigning Rscript to .R files or...)

Upvotes: 5

Views: 6018

Answers (3)

Karsten W.
Karsten W.

Reputation: 18500

For reference, here is the solution I came up with:

@echo off

set "rscript=I:\path\to\myscript.R"

for /r "c:\Program Files" %%F in (*Rscript.exe*) do (
  "%%~fF" "%rscript%" %*
  goto :eof
)

echo No Rscript.exe found. Maybe you need to install R.
pause

EDIT: using the suggestions of @Compo, I modified the batch file thus:

@Echo Off
SetLocal EnableExtensions

set "rscript=I:\path\to\myscript.R"

For /F "EOL=H Tokens=3*" %%G In (
    '"reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /S /F "R for Windows" /K /V "InstallLocation" 2> NUL | find "InstallLocation""'
) Do Set "rexe=%%G %%Hbin\x64\Rscript.exe"

if not defined rexe goto nope

"%rexe%" "%rscript%" %*
goto :eof

:nope
echo No Rscript.exe found. Maybe you need to install R.
pause

Here some notes I learned along the way.

  • .RData is associated to RStudio on my pc -- so not a good idea to look here.
  • SetLocal EnableExtension is not necessary on my pc, but it may be on other pc, hence I kept the line
  • The Tokens=3* defines %G as the third token and implicitly %H as all tokens after the third token. Crazy syntax.
  • 2> NUL means "ignore error messages"
  • The double quotation "'reg ...'" is really necessary, I wonder why

This works for me now. I can be sure that the pc the batch file will run on are x64 architectures and are installed under Program Files. Maybe later I need to add options to rscript. Also, I will have to figure out to use the latest R version in case there are more than one installed.

Upvotes: 0

Compo
Compo

Reputation: 38719

The first advice I'd offer, is that you check to see if its location was added to the registry under the file association with .RData files. If found, you could essentially replace RGui.exe with RScript.exe:

@Echo Off
SetLocal EnableExtensions
Set "Key=HKCU\Software\Classes\RWorkspace\Shell\Open\Command"
Set "RDir="
For /F "EOL=H Tokens=2*" %%G In ('%__AppDir__%reg.exe Query "%Key%" /VE 2^>NUL'
) Do Set "RDir=%~dpH"
If Not Defined RDir For /F "EOL=H Tokens=2*" %%G In (
    '%__AppDir__%reg.exe Query "HKLM%Key:~4%" /VE 2^>NUL') Do Set "RDir=%~dpH"
If Defined RDir Where /Q "%RDir%.":"RScript.exe" && (
    Set "RDir=%RDir%RScript.exe") || Set "RDir="
If Defined RDir Echo Your default RScript.exe absolute path is %RDir% & Pause

Other alternatives would be to check the registry uninstall information for the install location, and if found, append the \bin subdirectory and its respective architecture child:

@Echo Off
SetLocal EnableExtensions
Set "Key=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
Set "Sub=R for Windows"
Set "Val=InstallLocation"
Set "Reg=%__AppDir__%reg.exe"
Set "Find=%__AppDir__%find.exe"
Set "RDir="
For /F "EOL=H Tokens=2*" %%G In (
    '"%Reg% Query "%Key%" /S /F "%Sub%" /K /V "%Val%" 2>NUL|%Find% "\""'
) Do Set "RDir=%%H"
If Not Defined RDir If Defined PROCESSOR_ARCHITEW6432 (
    For /F "EOL=H Tokens=2*" %%G In (
        '"%Reg% Query "%Key%" /S /F "%Sub%" /K /V "%Val%" /Reg:32 2>NUL|%Find% "\""'
    ) Do Set "RDir=%%H")
If Not Defined RDir GoTo :EOF
If "%PROCESSOR_ARCHITECTURE:~-2%" == "86" (
    If Not Defined PROCESSOR_ARCHITEW6432 (Set "RDir=%RDir%\bin\i386"
) Else Set "RDir=%RDir%\bin\x64") Else Set "RDir=%RDir%\bin\x64"
Where /Q "%RDir%":"RScript.exe" && (Set "RDir=%RDir%\RScript.exe") || Set "RDir="
If Defined RDir Echo Your default RScript.exe absolute path is %RDir% & Pause

It may also be worth checking to see if the installation option to Save version number in registry was selected under Select Additional Tasks at installation time, (or later using RSetReg.exe or RSetReg.exe /Personal), then using the home directory path returned to append your subdirectories:

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "Reg=%__AppDir__%reg.exe"
Set "Find=%__AppDir__%find.exe"
Set "Key=HKCU\Software\R-core\R"
Set "Val=InstallPath"
Set "RDir="
For /F "EOL=H Tokens=2*" %%G In (
    '"%Reg% Query "%Key%" /S /F "%Val%" /V 2>NUL|%Find% "\""') Do Set "RDir=%%~H"
If Not Defined RDir For /F "EOL=H Tokens=2*" %%G In (
    '"%Reg% Query "HKLM%Key:~4%" /S /F "%Val%" /V 2>NUL|%Find% "\""'
) Do Set "RDir=%%~H"
If Not Defined RDir GoTo :EOF
If "%PROCESSOR_ARCHITECTURE:~-2%" == "86" (
    If Not Defined PROCESSOR_ARCHITEW6432 (Set "RDir=%RDir%\bin\i386"
) Else Set "RDir=%RDir%\bin\x64") Else Set "RDir=%RDir%\bin\x64"
Where /Q "%RDir%":"RScript.exe" && (Set "RDir=%RDir%\RScript.exe") || Set "RDir="
If Defined RDir Echo Your default RScript.exe absolute path is %RDir% & Pause

It would only be if one of those methods failed to provide a location, would I consider performing a search of the system drive, or possibly other available volumes for an executable file.

Upvotes: 2

T3RR0R
T3RR0R

Reputation: 2961

Command output can be captured into a variable using a for /F loop. If conditions or piping the output into find or findstr can further filter that output.

For a simple case of capturing just the first line of output, the below should suffice.

@echo off
Setlocal ENABLEdelayedexpansion
For /F "Delims=" %%0 In ('where /r "c:\Program Files" Rscript.exe') do If "!scriptpath!" == "" Set "scriptpath=%%~0"

Upvotes: 2

Related Questions