While writing some batch scripts I needed to pull the msbuild tools path from the registry and into a variable, simple I would have thought but due to the way REG QUERY returns results, not so easy. I had varying levels of success with solutions found on StackOverflow however it seems that at some point Microsoft changed the delimiter in the REG QUERY return string to be four spaces instead of a tab character and it's possible for the key value to have a space in, so splitting on a space is out of the question.

However with a combination of for loops, delayed expansion and string replacement it is possible to grab a single registry keys value and store it in a variable.


    setlocal enabledelayedexpansion
    
    for /f "tokens=* delims=" %%A in ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath') do (
        set regstr=%%A
        set "regstr=!regstr:    =    |!"
    )
    
    for /f "tokens=3 delims=    |" %%X in ("%regstr%") do (
            SET "actualValue=%%X"
    )
    

How it Works


    setlocal enabledelayedexpansion
    

This is required to allow access to the actual value of a variable in a loop rather than the one cached at loop start, without this our string replacement wouldn't work.


    for /f "tokens=* delims=" %%A in ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath') do (
    

Here we trigger a loop which will route the entire string per result into the variable %%A with 'REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath' being the command we are using to find a specific key in the registry, for more on how this works check Reg.exe

The output of this command should be


    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0
    MSBuildToolsPath    REG_SZ    C:\Program Files (x86)\MSBuild\14.0\bin\amd64\
    

Because we are looping the first line will end up being ignored.


    set regstr=%%A
    set "regstr=!regstr:    =    |!"
    

Inside the loop when we have the entire string returned from the command we need to replace the instances of four space characters with a splittable delimiter, we use tab followed by a pipe. First we set the loop variable to a standard variable so we can use variable replace syntax. Then we replace the four space characters with our " |" delimiter and store it back into the same variable, the variable access uses ! instead of % here because we are using delayed expansion.

After replacement %regstr% should be


    MSBuildToolsPath    |REG_SZ |C:\Program Files (x86)\MSBuild\14.0\bin\amd64\
    

    for /f "tokens=3 delims=    |" %%X in ("%regstr%") do (
            SET "actualValue=%%X"
    )
    

Now we know that the third element of the string is the only one we need, so we split on our delimiter and just grab the 3rd token and stick it in a different variable.