Tuesday, June 26, 2007

How To ENABLEDELAYEDEXPANSION

ENABLEDELAYEDEXPANSION is a useful property that allow you to do what you think should happen when you write a for loop or an if block. Consider this example.

set COUNT=0

for %%var in (1 2 3 4) do (

  set /A COUNT=%COUNT% + 1

  echo %COUNT%

)

Now in any other scripting or programming language, this would be just fine. Not so in windows batch. Since batch processor treats the whole for loop as one command, it expands the variables once and only once, before it executes the loop. So you end up with %COUNT% being expanded to its value, which is 0, before you start the loop, and you end up printing 0 four times in a row.

That's where delayed expansion comes in. As the name suggests, delayed expansion makes batch processor delay expanding the variable to its value until it actually loops through it.

But to make that happen, you need to do two things.

1. Enable delayed expansion. You can do this by doing setlocal ENABLEDELAYEDEXPANSION at the beginning of your script.

2. Use ! instead of % to expand environment variable value.

Now here's that example again using delayed expansion:

setlocal ENABLEDELAYEDEXPANSION

set COUNT=0

for %%var in (1 2 3 4) do (

  set /A COUNT=!COUNT! + 1

  echo !COUNT!

)

This time you will see 1 2 3 4 being printed, as you expect.

Another way of turning on delayed expansion is through the registry. You can go and add it manually through regedt32.exe, or you can load a registry file like the one shown here:

Windows Registry Editor Version 5.00[HKEY_CURRENT_USER\Software\Microsoft\Command Processor]

"DelayedExpansion"=dword:00000001

Just save it to a file called enabledelayedexpansion.reg or something, and just invoke that file from the command line.

enabledelayedexpansion.reg

This will enable delayed expansion for current user. You can do the same for HKEY_LOCAL_MACHINE.
You need to start a new console window to see its effect. To check, simply do

echo !COMPUTERNAME!

in the new command console. If it prints your computername, then it recognizes the ! variable expansion, which means delayed expansion is enabled.
This way you don't have to do setlocal ENABLEDELAYEDEXPANSION. But watch out, you need to make sure this thing is enabled if you are planning on skipping setlocal ENABLEDELAYEDEXPANSION in your script.

I'll get into how to check for this from your script some other time.

6 comments:

Chris Marx said...

thank you! this was the first post that actually worked for executing multiple statements within the for loop-

Fane said...

Thanks! I desperately searched for the reason the For loop doesn't execute how I was hoping it would.

DK said...

One important correction: setlocal ENABLEDELAYEDEXPANSION is available in Vista, but not in XP. In XP, you have to enable it via registry.

Franc said...

Thanks, it's very usefull!

levidos said...

thanks!

Yan said...

This is very helpful. By the way, in windows 7, we could use "%" instead of "!".