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.