Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying DelayedExpansion variables inside a loop

I've got the following code which finds and prints out the values of of DWORD type within the key at SpecialUserRegDir. Secondary part of this code is a number that simply increases with each iteration. Unfortunately, I can't find a way to access the variables, that seem to be getting calculated correctly.

@echo OFF
@setlocal EnableExtensions  EnableDelayedExpansion

set SpecialUserRegDir=HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
set number=0
set /a number+=1

REG QUERY "%SpecialUserRegDir%" /s | for /F %%f in ('findstr "REG_DWORD"') do @( 
    set /a number+=1        :: Output: Values I need (2,3 etc)
    @Echo !number!          :: Output: !number!
    @Echo %number%          :: Output: 1
    @echo %%f               :: Output: [name of registry value]
)
@Echo !number!              :: Output: 1
@Echo %number%              :: Output: 1

The registry part is not so important, because it works. I am wondering if there's a way to keep the loop structure and access the values of number from within the loop.

EDIT: Only 1 of the outputs changed with new code:

for /F %%f in ('REG QUERY "%SpecialUserRegDir%" /s ^| findstr "REG_DWORD"') do ( 
            set /a number+=1        :: Output: Values I need (2,3 etc)
            @Echo !number!          :: Output: !number!
            @Echo %number%          :: Output: 1
            @echo %%f               :: Output: [name of registry value]
        )
        @Echo !number!              :: Output: 4 (correct, because there are 3 values)
        @Echo %number%              :: Output: 1 (expected....)

EDIT 2: Ignore the first edit. I had multiple notepads with code opened and saved the new code on older version without EnableDelayedExpansion.

like image 554
Zero Avatar asked Mar 05 '26 02:03

Zero


1 Answers

Your problem is the pipe, as this disables the delayed expansion!
Why?
A pipe create two new instances of cmd.exe both with the default settings (disabled delayed expansion , ...) and it runs in the command line context which works different than the batch context.

You can solve this very easy by moving the pipe into the for loop.
Then you can also remove the @ signs.

...
for /F %%f in ('REG QUERY "%SpecialUserRegDir%" /s ^| findstr "REG_DWORD"') do ( 
    set /a number+=1        :: Output: Values I need (2,3 etc)
    Echo !number!          :: Output: !Iterator!
    Echo %number%          :: Output: 1
    echo %%f               :: Output: [name of registry value]
)

The ^| is necessary to force the pipe functionallity inside the FOR loop, else the batch parser splits the line at the pipe character and fails.

The next problem is that your FOR/F can't fetch the registry value this way.
You need to add the tokens options to access the n-th element.

for /F "tokens=1-3" %%A in ('REG QUERY "%SpecialUserRegDir%" /s ^| findstr "REG_DWORD"') do ( 
  echo key=%%A type=%%B value=%%C
)
like image 170
jeb Avatar answered Mar 08 '26 22:03

jeb



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!