3

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.

Zero
  • 1,562
  • 1
  • 13
  • 29

1 Answers1

4

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
)
jeb
  • 78,592
  • 17
  • 171
  • 225
  • I've tried this code. The post-loop !number! now gets the right info, but the inside of the loop hasn't changed at all. Although, I think I understand the issue you pointed out, I'll experiment a little more tomorrow and see how it turns out. – Zero May 11 '16 at 12:54
  • I added the explanation of your second problem (missing token option) – jeb May 11 '16 at 12:55