3. Working with the Registry¶
What & why¶
The registry is where Windows and installed software keep configuration: file associations, startup programs, environment variables, uninstall entries, policy. reg.exe reads and writes it from batch. This is powerful and dangerous — a bad reg add to HKLM can break the machine — so the emphasis here is on reading safely and writing carefully.
reg query — reading¶
rem One value:
reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Hidden
rem A whole key (its values):
reg query "HKCU\Environment"
rem Recurse:
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s
rem Search for a value name or data:
reg query "HKLM\SOFTWARE" /f "Python" /s /k &rem /k = match key names
Parsing a single value with for /F¶
reg query output for a value looks like:
Extract the data (3rd token onward, tab/space delimited):
set "val="
for /F "tokens=2,*" %%a in ('reg query "HKCU\...\Advanced" /v Hidden 2^>nul ^| findstr /i "Hidden"') do set "val=%%b"
rem %%a = REG_DWORD, %%b = 0x1
echo Hidden = %val%
More robust (skip to the line with the value name, take the last token):
for /F "tokens=1,2*" %%a in ('reg query "HKCU\Console" /v FontSize 2^>nul ^| findstr /ri "REG_"') do (
set "name=%%a"
set "type=%%b"
set "data=%%c"
)
Value data can contain spaces
REG_SZ data like C:\Program Files\App has spaces. Use tokens=1,2* so the third capture grabs "the rest," and don't split on it further. Value names with spaces exist too and make findstr matching ambiguous — match on the REG_ type line instead when you can.
Check existence¶
reg query "HKLM\SOFTWARE\MyApp" >nul 2>&1 && echo installed || echo not installed
reg query "HKCU\Environment" /v MY_VAR >nul 2>&1 && echo MY_VAR is set
reg query returns 1 when the key or value doesn't exist.
reg add — writing¶
reg add "HKCU\Software\MyApp" /v "Version" /t REG_SZ /d "1.2.3" /f
reg add "HKCU\Software\MyApp" /v "Enabled" /t REG_DWORD /d 1 /f
reg add "HKCU\Software\MyApp" /v "Path" /t REG_EXPAND_SZ /d "%%USERPROFILE%%\MyApp" /f
| Switch | Meaning |
|---|---|
/v NAME |
value name (omit + /ve for the "(Default)" value) |
/t TYPE |
REG_SZ, REG_DWORD, REG_EXPAND_SZ, REG_MULTI_SZ, REG_BINARY, REG_QWORD |
/d DATA |
the data |
/f |
force — no "overwrite?" prompt (needed in scripts) |
/s SEP |
separator char for REG_MULTI_SZ (default \0) |
REG_EXPAND_SZ with a literal %USERPROFILE%: in a batch script you must write %%USERPROFILE%% so one % survives to the registry.
reg delete — removing¶
reg delete "HKCU\Software\MyApp" /v "OldSetting" /f &rem one value
reg delete "HKCU\Software\MyApp" /f &rem the whole key + subkeys
reg delete "HKCU\Software\MyApp" /va /f &rem all values, keep subkeys
Danger
reg delete "HKLM\SOFTWARE\..." /f has no undo and no Recycle Bin. Export first (below), double-check the path isn't built from an empty variable, and prefer HKCU over HKLM whenever the setting is per-user.
Backup & restore: reg export / reg import¶
reg export "HKCU\Software\MyApp" "%~dp0myapp-backup.reg" /y
rem ... make changes ...
rem to roll back:
reg import "%~dp0myapp-backup.reg"
Always reg export the key before a script modifies it in place. .reg files are text — you can inspect them.
Common real tasks¶
Add a startup program (per-user, no admin)¶
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "MyTool" /t REG_SZ /d "\"%~f0\" --run" /f
rem remove:
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "MyTool" /f
Read a persistent environment variable (not the volatile session one)¶
(Editing PATH via reg then broadcasting WM_SETTINGCHANGE is fiddly — setx is the batch-friendly way to write a persistent var, though it truncates at 1024 chars and doesn't affect the current session.)
Enumerate subkeys¶
for /F "tokens=*" %%k in ('reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"') do (
for /F "tokens=2*" %%n in ('reg query "%%k" /v DisplayName 2^>nul ^| findstr /i "DisplayName"') do echo %%o
)
(Lists installed program names. 2>nul because not every subkey has DisplayName.)
32-bit vs 64-bit views¶
On 64-bit Windows, 32-bit and 64-bit processes see different HKLM\SOFTWARE (the 32-bit view is redirected to ...\WOW6432Node). Force a view:
A batch script launched from a 32-bit parent may be querying the wrong hive without /reg:64.
Common mistakes¶
reg addwithout/f— prompts "overwrite? (Yes/No)" and hangs an unattended script.- Splitting value data on spaces — use
tokens=1,2*and treat the rest as one string. %VAR%in/dforREG_EXPAND_SZ— batch expands it now; you wanted%%VAR%%.- Writing to
HKLMwithout admin — "Access is denied"; check elevation (Intermediate Lesson 9). reg deletewith a path from an unvalidated variable — could target something huge. Guard it.- No
reg exportbefore modifying — no way back. - Wrong bitness view — 32-bit script silently reads
WOW6432Node. Add/reg:64. - Assuming
reg queryerrorlevel —1for missing is reliable; parse failures may still be0with junk output. REG_MULTI_SZediting — the\0separators make this genuinely painful in batch; consider PowerShell.
Exercises¶
- Read the current user's
TEMPvalue fromHKCU\Environmentand print it, handling the "not set" case. - Detect whether a program (say "7-Zip") is installed by searching the
Uninstallkeys; print itsDisplayNameandDisplayVersionif found. - Write
:reg_get KEY VALUE outvarthat returns the data of a single value (any type, spaces intact) or empty if missing. - Add your script to
HKCU\...\Runas a startup item, then remove it. Verify withreg queryeach time. - Export a test key, add three values, delete one, then restore from the export and confirm you're back to the original state (
reg exportagain andfcthe two.regfiles). - Query
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion/v ProductNamewith and without/reg:64from the same script; note any difference on a 64-bit machine.
Recap¶
reg query KEY /v NAMEreads; parse withfor /F "tokens=1,2*"and treat token 3 as the whole (possibly spaced) data. Missing key/value → errorlevel1.reg add ... /t TYPE /d DATA /fwrites (always/fin scripts); use%%VAR%%forREG_EXPAND_SZliterals.reg delete ... /fis irreversible —reg exportfirst, guard the path, preferHKCU.reg export/reg importare your backup/restore.- Add
/reg:64(or/reg:32) to avoid the WOW6432Node redirection surprise. - For
REG_MULTI_SZandPATHbroadcasting, consider PowerShell instead.