Search code examples
batch-filefor-loopregistrystring-parsing

Get all results from for loop in batch (%%a %%b %%c ... %%z)


I'm trying to get the JavaHome registry key's path, and so far I have this:

for /f "skip=2 tokens=3" %%x in ('reg query "HKLM\SOFTWARE\JavaSoft\%~1" /v CurrentVersion') do set JavaTemp=%%x

for /f "skip=2 tokens=3*" %%a in ('reg query "HKLM\SOFTWARE\JavaSoft\%~1\%JavaTemp%" /v JavaHome') do set JAVA_HOME=%%a %%b
echo %JAVA_HOME%

Note: %1 can be "JRE" or "JDK"

Reference: http://www.rgagnon.com/javadetails/java-0642.html

However this only gets the first two portions of the path (%%a %%b) split by whitespace. If there's more than one space in the path, this will fail to output the whole path.

I'm not too experienced with for-loops in Batch, so my question is: how can I get all of the tokens found? (without having to do %%a %%b ... %%z) Can I use a nested for-loop somehow?

My initial thinking was that I could just do

set JAVA_HOME=%%*

But this doesn't work.


Solution

  • @echo off
    setlocal
    
    set "Arg1=%~1"
    
    if not defined Arg1 (
        >&2 echo No argument passed for Arg1
        exit /b 1
    )
    
    for /f "tokens=1,2*" %%A in (
        '2^>nul reg query "HKLM\SOFTWARE\JavaSoft\%Arg1%" /v CurrentVersion'
    ) do if /i "%%~A" == "CurrentVersion" set "JavaTemp=%%~C"
    
    if not defined JavaTemp (
        >&2 echo JavaTemp undefined
        exit /b 2
    )
    
    for /f "tokens=1,2*" %%A in (
        '2^>nul reg query "HKLM\SOFTWARE\JavaSoft\%Arg1%\%JavaTemp%" /v JavaHome'
    ) do if /i "%%~A" == "JavaHome" set "JAVA_HOME=%%~C"
    
    if not defined JAVA_HOME (
        >&2 echo JAVA_HOME undefined
        exit /b 3
    ) else echo %JAVA_HOME%
    
    exit /b 0
    

    Excerpt from for /?:

    If the last character in the tokens= string is an asterisk, then an additional variable is allocated and receives the remaining text on the line after the last token parsed.

    Token options 1,2*:

    • 1 gets the word representing the registry value i.e. %%A == JavaHome.
    • 2 gets the word representing the registry type i.e. %%B == REG_SZ.
    • * gets the remaining text i.e. %%C == C:\Program Files\Java\jre1.6.0_06

    No skip option used as the link from Real's HowTo in the question shows an integer variation with WinXP and Win7. A check of the 1st token value decides the line to use which may be common to WinXP, Win7 and later.

    A nested for loop is not needed for this task.