How can I get the value of a registry key from within a batch script?
I need to use a REG QUERY command to view the value of a key and set the result into a variable with this command:
FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "KeyName" /v ValueName') DO SET Variable=%%B
But if the key doesnt exists i get an error shown in the console. I need to hide this error! I tried putting a 2>nul after the command to stop the stderr, but this works if i only call the command:
REG QUERY "KeyName" /v ValueName 2>nul
If i put it into the FOR command like this:
FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "KeyName" /v ValueName') DO SET Variable=%%B 2>nul
The error is shown. So does anyone know how to hide the error? Or maybe another command too see if a key exists or not?
Thanks
PS: I'm using Windows XP
Solution 1:
This works for me:
@echo OFF
setlocal ENABLEEXTENSIONS
set KEY_NAME="HKEY_CURRENT_USER\Software\Microsoft\Command Processor"
set VALUE_NAME=DefaultColor
FOR /F "usebackq skip=4 tokens=1-3" %%A IN (`REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul`) DO (
set ValueName=%%A
set ValueType=%%B
set ValueValue=%%C
)
if defined ValueName (
@echo Value Name = %ValueName%
@echo Value Type = %ValueType%
@echo Value Value = %ValueValue%
) else (
@echo %KEY_NAME%\%VALUE_NAME% not found.
)
usebackq
is needed since the command to REG QUERY
uses double quotes.
skip=4
ignores all the output except for the line that has the value name, type and value, if it exists.
2^>nul
prevents the error text from appearing. ^
is the escape character that lets you put the >
in the for
command.
When I run the script above as given, I get this output:
Value Name = DefaultColor
Value Type = REG_DWORD
Value Value = 0x0
If I change the value of VALUE_NAME
to BogusValue
then I get this:
"HKEY_CURRENT_USER\Software\Microsoft\Command Processor"\BogusValue not found.
Solution 2:
This work for me with variable that contains spaces on Windows 7:
FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKEY_LOCAL_MACHINE\Software\SomeAPP" /v ValueName`) DO (
set appdir=%%A %%B
)
ECHO %appdir%
Variable A
contains all data before first space, B
- rest part of ValueName (including further spaces), so appdir = ValueName
Solution 3:
This one-liner is pretty much the same as your original try with a couple of additions. It works with paths including spaces, and works in both XP and Windows 7 even if the key is not found (and hides the error). %fn%
will be empty if the key does not exist. This example gets the current desktop background filename:
for /f "tokens=2*" %%a in ('reg query "HKEY_CURRENT_USER\Control Panel\Desktop" /v Wallpaper 2^>^&1^|find "REG_"') do @set fn=%%b
This command uses tokens=2*
with %%a
as the loop variable but consumes %%b
to correctly handle spaces. When using tokens=2*
, the loop variable %%a
is assigned the value in the second token (in this case, REG_SZ
) and %%b
is assigned the remainder of the line after the next group of delimiter characters, including all internal delimiter characters. This means that %%b
will correctly replicate delimiter characters—even if multiple delimiter characters are clustered together. For example, the value might be C:\A weird path\blah.png
. This technique of reading the value would correctly preserve the two spaces between C:\A
and weird
.
Solution 4:
Based on tryingToBeClever solution (which I happened to also stumble upon and fixed myself by trial-and-error before finding it), I also suggest passing the result output of reg query
through find
in order to filter undesired lines due to the ! REG.EXE VERSION x.y
inconsistency. The find
filtering and tokens
tweaking also allows to pick exactly what we want (typically the value). Also added quotes to avoid unexpected results with key/value names containing spaces.
Final result proposed when we are only interested in fetching the value:
@echo off
setlocal ENABLEEXTENSIONS
set KEY_NAME=HKCU\Software\Microsoft\Command Processor
set VALUE_NAME=DefaultColor
for /F "usebackq tokens=1,2,*" %%A IN (`reg query "%KEY_NAME%" /v "%VALUE_NAME%" 2^>nul ^| find "%VALUE_NAME%"`) do (
echo %%C
)
A potential caveat of using find
is that the errorlevel set by reg
when errors occur is now obfuscated so one should only use this approach for keys known to be there and/or after a previous validation.
A tiny additional optimization (add skip=1
to avoid processing the first line of output) can be done in cases when the key name also contains the value name (as it is the case with HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion
and CurrentVersion
) but removes most flexibility so should only be used in particular use-cases.
Solution 5:
@echo off
setlocal ENABLEEXTENSIONS
set KEY_NAME=HKLM\SOFTWARE\Wow6432Node\Acme Software Inc\Common
set VALUE_NAME=InstallDir
FOR /F "tokens=2*" %%A IN ('REG.exe query "%KEY_NAME%" /v "%VALUE_NAME%"') DO (set pInstallDir=%%B)
echo %pInstallDir%
That works for me in Win7 where the key has a space and the value also has a space. So saving the above in c:\temp as test.bat, open a cmd window and run it.
C:\temp>test
C:\Program Files (x86)\acme Software Inc\APP\